Trong MariaDB, EXCEPT
toán tử trả về các hàng từ truy vấn đầu vào bên trái mà truy vấn đầu vào bên phải không xuất ra.
Một cách khác để đặt nó là nó trả về tất cả các hàng từ SELECT
bên trái tập hợp kết quả ngoại trừ các hàng ở bên phải SELECT
tập hợp kết quả.
Cú pháp
Cú pháp chính thức như sau:
SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
Ở trên cũng bao gồm INTERSECT
và UNION
các toán tử trong cú pháp, vì cú pháp tương tự áp dụng cho các toán tử đó.
Từ MariaDB 10.4.0, dấu ngoặc đơn có thể được sử dụng để chỉ định mức độ ưu tiên.
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 | +-------------+ | Ben | | Cathy | +-------------+
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, nó trả về các hàng riêng biệt, vì vậy chỉ một hàng được trả về cho Cathy
, mặc dù có hai giáo viên có tên đó. Chúng tôi có thể thay đổi hành vi này - nhiều hơn về điều này sau.
Chúng tôi cũng có thể chuyển đổi nó và đặ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 | +-------------+
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 | +-------------+ | Ben | | Cathy | +-------------+
Phiền bạn, EXCEPT
toán tử giúp đơn giản hóa mã một cách đáng kể.
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.
Trước MariaDB 10.5.0, DISTINCT
ngầm là lựa chọn duy nhất của chúng tôi - chúng tôi không thể chỉ định ALL
. Tuy nhiên, MariaDB 10.5.0 đã giới thiệu EXCEPT ALL
và EXCEPT DISTINCT
cú pháp.
Điều này có nghĩa là bây giờ chúng ta có thể thực hiện các truy vấn như sau:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Kết quả:
+-------------+ | TeacherName | +-------------+ | Cathy | | Ben | | Cathy | | Bill | +-------------+
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.
Đố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.
Và đây là một ví dụ sử dụng rõ ràng DISTINCT
nhà điều hành:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Kết quả:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Như mong đợi, chúng tôi nhận được cùng một kết quả mà chúng tôi sẽ nhận được nếu chúng tôi xóa DISTINCT
nhà điều hành.
Trong MariaDB 10.6.1, MINUS
được giới thiệu như một từ đồng nghĩa với EXCEPT
. Do đó, chúng ta có thể sử dụng MINUS
thay vì EXCEPT
trong MariaDB 10.6.1 trở lên.