Trong PostgreSQL, EXCEPT
toán tử trả về các hàng được trả về bởi truy vấn đầu vào bên trái mà không được trả về bởi truy vấn đầu vào bên phải. Đây cũng có thể được gọi là sự khác biệt giữa hai truy vấn.
Cú pháp
Cú pháp như sau:
query1 EXCEPT [ALL] query2
Các bản sao sẽ bị loại trừ trừ khi EXCEPT ALL
được sử dụng.
Ví dụ
Giả sử chúng ta có các bảng sau:
SELECT * FROM Teachers;
SELECT * FROM Students;
Kết quả:
teacherid | teachername -----------+------------- 1 | Warren 2 | Ben 3 | Cathy 4 | Cathy 5 | Bill 6 | Bill studentid | studentname -----------+------------- 1 | Faye 2 | Jet 3 | Spike 4 | Ein 5 | Warren 6 | Bill
Chúng ta có thể sử dụng EXCEPT
toán tử để trả lại giáo viên không phải là sinh viên:
SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Kết quả:
teachername ------------- Cathy Ben
Vì vậy, chúng tôi chỉ nhận được các giá trị xuất hiện trong Teachers
bảng cũng không xuất hiện trong Students
bàn.
Theo mặc định, EXCEPT
toán tử trả về các hàng riêng biệt. Vì vậy, trong ví dụ của chúng tôi, chỉ một hàng được trả về cho Cathy
, mặc dù có hai giáo viên có tên đó.
Ví dụ trên tương đương với truy vấn sau:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Kết quả:
teachername ------------- Cathy Ben
Đây là kết quả tương tự mà chúng tôi nhận được khi không có DISTINCT
rõ ràng từ khóa. Chúng tôi có thể bao gồm các bản sao với ALL
từ khóa (thêm về điều này sau).
Chúng ta có thể nhận được các kết quả khác nhau, tùy thuộc vào bảng nào ở bên trái và bảng nào ở bên phải. Đây là một ví dụ đặt Students
bảng bên trái và Teachers
ở bên phải:
SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Kết quả:
studentname ------------- Faye Jet Spike Ein
Lần này, chúng tôi có những sinh viên không phải là giáo viên.
Bao gồm các bản sao
Theo mặc định, EXCEPT
toán tử áp dụng ngầm một DISTINCT
hoạt động. Nói cách khác, nó chỉ trả về các giá trị riêng biệt theo mặc định.
Chúng tôi có thể bao gồm ALL
từ khóa để bao gồm các bản sao trong kết quả của chúng tôi:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Kết quả:
teachername ------------- Cathy Cathy Bill Ben
Lần này chúng ta có bốn hàng, thay vì hai hàng như trong ví dụ đầu tiên.
Chúng ta có thể thấy rằng cả hai Cathys đã được trả lại thay vì chỉ một như trong ví dụ đầu tiên của chúng tôi.
Còn đối với Bill? Có hai Hóa đơn trong Teachers
bảng, nhưng chỉ có một được trả lại ở đây. Đó có thể là do có một Hóa đơn trong Students
bảng này sẽ loại trừ một trong các Hóa đơn khỏi kết quả của chúng tôi.
Một giải pháp thay thế
Có thể nhận được kết quả tương tự mà không cần sử dụng EXCEPT
nhà điều hành. Ví dụ:chúng tôi có thể viết lại ví dụ đầu tiên của chúng tôi thành ví dụ này:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);
Kết quả:
teachername ------------- Cathy Ben