Cú pháp cũ, chỉ liệt kê các bảng và sử dụng WHERE
mệnh đề để chỉ định tiêu chí tham gia, đang bị phản đối trong hầu hết các cơ sở dữ liệu hiện đại.
Nó không chỉ để hiển thị, cú pháp cũ có khả năng mơ hồ khi bạn sử dụng cả INNER và OUTER tham gia trong cùng một truy vấn.
Tôi sẽ cho bạn một ví dụ.
Giả sử bạn có 3 bảng trong hệ thống của mình:
Company
Department
Employee
Mỗi bảng chứa nhiều hàng, được liên kết với nhau. Bạn có nhiều công ty và mỗi công ty có thể có nhiều bộ phận và mỗi bộ phận có thể có nhiều nhân viên.
Ok, vậy bây giờ bạn muốn làm như sau:
Liệt kê tất cả các công ty, và bao gồm tất cả các bộ phận của họ, và tất cả nhân viên của họ. Lưu ý rằng một số công ty chưa có bộ phận nào, nhưng hãy đảm bảo bạn cũng bao gồm họ. Hãy chắc chắn rằng bạn chỉ truy xuất các phòng ban có nhân viên, nhưng luôn liệt kê tất cả các công ty.
Vì vậy, bạn làm điều này:
SELECT * -- for simplicity
FROM Company, Department, Employee
WHERE Company.ID *= Department.CompanyID
AND Department.ID = Employee.DepartmentID
Lưu ý rằng cái cuối cùng có một sự tham gia bên trong, để đáp ứng các tiêu chí mà bạn chỉ muốn các phòng ban với mọi người.
Ok, vậy chuyện gì xảy ra bây giờ. Vấn đề là, nó phụ thuộc vào công cụ cơ sở dữ liệu, trình tối ưu hóa truy vấn, chỉ mục và thống kê bảng. Hãy để tôi giải thích.
Nếu trình tối ưu hóa truy vấn xác định rằng cách để thực hiện việc này trước tiên là lấy một công ty, sau đó tìm các phòng ban và sau đó tham gia nội bộ với nhân viên, bạn sẽ không nhận được bất kỳ công ty nào không có bộ phận.
Lý do cho điều này là WHERE
mệnh đề xác định hàng nào kết thúc trong kết quả cuối cùng, không phải là các phần riêng lẻ của hàng.
Và trong trường hợp này, do tham gia bên trái, cột Department.ID sẽ là NULL, và do đó, khi nói đến INNER THAM GIA cho nhân viên, không có cách nào để thực hiện ràng buộc đó đối với hàng Nhân viên, và vì vậy nó sẽ không xuất hiện.
Mặt khác, nếu trình tối ưu hóa truy vấn quyết định giải quyết việc tham gia của nhân viên bộ phận trước, sau đó thực hiện tham gia trái với các công ty, bạn sẽ thấy họ.
Vì vậy, cú pháp cũ là mơ hồ. Không có cách nào để xác định những gì bạn muốn, mà không xử lý các gợi ý truy vấn và một số cơ sở dữ liệu không có cách nào cả.
Nhập cú pháp mới, với điều này bạn có thể chọn.
Ví dụ: nếu bạn muốn tất cả các công ty, như mô tả vấn đề đã nêu, đây là những gì bạn sẽ viết:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID
Tại đây, bạn xác định rằng bạn muốn nhân viên bộ phận tham gia được thực hiện như một người tham gia, và sau đó rời khỏi tham gia kết quả của điều đó với các công ty.
Ngoài ra, giả sử bạn chỉ muốn các phòng ban có chứa chữ X trong tên của họ. Một lần nữa, với kiểu tham gia cũ, bạn cũng có nguy cơ mất công ty, nếu nó không có bất kỳ bộ phận nào có tên X, nhưng với cú pháp mới, bạn có thể làm điều này:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID AND Department.Name LIKE '%X%'
Mệnh đề bổ sung này được sử dụng để nối, nhưng không phải là bộ lọc cho toàn bộ hàng. Vì vậy, hàng có thể xuất hiện cùng với thông tin công ty, nhưng có thể có NULL trong tất cả các cột của bộ phận và nhân viên cho hàng đó, bởi vì không có bộ phận nào có chữ X trong tên của công ty đó. Điều này là khó với cú pháp cũ.
Đây là lý do tại sao, trong số các nhà cung cấp khác, Microsoft đã từ chối cú pháp nối ngoài cũ, nhưng không phải là cú pháp nối bên trong cũ, kể từ SQL Server 2005 trở lên. Cách duy nhất để nói chuyện với cơ sở dữ liệu chạy trên Microsoft SQL Server 2005 hoặc 2008, sử dụng cú pháp nối ngoài kiểu cũ, là đặt cơ sở dữ liệu đó ở chế độ tương thích 8.0 (còn gọi là SQL Server 2000).
Ngoài ra, cách cũ, bằng cách ném một loạt các bảng vào trình tối ưu hóa truy vấn, với một loạt các mệnh đề WHERE, giống như nói "bạn đang ở đây, làm tốt nhất có thể". Với cú pháp mới, trình tối ưu hóa truy vấn có ít việc phải làm để tìm ra phần nào đi cùng nhau.
Vì vậy, có bạn có nó.
TRÁI PHIẾU VÀ THAM GIA là làn sóng của tương lai.