Câu 1Câu nào mô tả đúng SELECT name FROM employee UNION SELECT name FROM contractor;?
Phép toán tập hợp — UNION / INTERSECT / EXCEPT
Học phép toán tập hợp SQL UNION / UNION ALL / INTERSECT / EXCEPT với dữ liệu nhân viên và nhà thầu, tất cả chạy trực tiếp trên trình duyệt của bạn.
Dữ liệu dùng trong bài viết này — employee và contractor
Phép toán tập hợp (các phép toán kết hợp nhiều kết quả SELECT thành một như hợp, giao, hoặc hiệu của các tập) là cú pháp để xếp chồng dọc các kết quả được lấy riêng rẽ, hoặc lấy ra các hàng chung của cả hai hoặc các hàng chỉ xuất hiện ở một phía.
Bạn sẽ làm việc với bốn cái: UNION (hợp), UNION ALL (hợp giữ trùng lặp), INTERSECT (giao), và EXCEPT (hiệu).
Dữ liệu là bảng nhân viên employee (30 hàng) và bảng nhà thầu contractor (6 hàng).
Bạn sẽ thử bốn phép toán tập hợp lần lượt từng cái — nối hai kết quả với các điều kiện khác nhau bên trong employee, hoặc kết hợp các kết quả lấy từ các bảng khác nhau như employee và contractor thành một.
Tiền đề của phép toán tập hợp — tính tương thích UNION
Cả bốn phép toán tập hợp nối hai hoặc nhiều kết quả SELECT theo dạng SELECT ... operator SELECT ....
Tiền đề để nối là SELECT trên và dưới phải tương thích UNION (số cột bằng nhau, và các kiểu cột tương ứng tương thích).
SELECT name FROM employee và SELECT name FROM contractor đều là một cột chuỗi đơn, nên chúng tương thích.
Mặt khác, SELECT name FROM employee và SELECT name, city FROM contractor có số cột khác nhau, nên bạn không thể nối chúng.
-- tương thích UNION: cả hai phía đều 2 cột (name, city)
SELECT name, city FROM employee WHERE city = 'Tokyo'
UNION
SELECT name, city FROM contractor
ORDER BY name;
-- ORDER BY chỉ đặt một lần ở cuối cùng
-- bạn không thể viết ORDER BY riêng cho mỗi SELECT ở giữa
UNION và UNION ALL — loại bỏ trùng lặp hoặc giữ chúng
UNION xếp chồng dọc hai kết quả và gộp các hàng hoàn toàn giống nhau thành một (loại bỏ trùng lặp).
UNION ALL không loại bỏ trùng lặp và giữ mọi hàng từ cả hai phía nguyên trạng.
Khi bạn không cần loại bỏ trùng lặp, hoặc khi bạn muốn giữ "bao nhiêu hàng xuất hiện ở cả hai," hãy dùng UNION ALL.
UNION chạy một phép sắp xếp nội bộ để phát hiện trùng lặp, nên UNION ALL là phép toán nhẹ hơn.
Ví dụ dưới đây nối kết quả "sống ở Kyoto" và kết quả "lương từ 7 triệu trở lên" bên trong employee.
Một nhân viên thỏa cả hai điều kiện trở thành 1 hàng với UNION, và 2 hàng với UNION ALL.
-- UNION: các hàng trùng lặp được gộp thành một
SELECT name FROM employee WHERE city = 'Osaka'
UNION
SELECT name FROM employee WHERE salary >= 5000000
ORDER BY name;
-- UNION ALL: trùng lặp được giữ (các hàng khớp cả hai xuất hiện hai lần)
SELECT name FROM employee WHERE city = 'Osaka'
UNION ALL
SELECT name FROM employee WHERE salary >= 5000000
ORDER BY name;
INTERSECT và EXCEPT — hàng chung và hàng khác biệt
INTERSECT(giao) trả về chỉ các hàng xuất hiện chung trong cả hai kết quả.EXCEPT(hiệu) trả về các hàng có trong kết quả trên nhưng không có trong kết quả dưới.
Cả hai tự động loại bỏ trùng lặp (cùng hành vi như UNION).
EXCEPT là một phép toán bất đối xứng mà kết quả thay đổi nếu bạn hoán đổi phía trên và phía dưới — A EXCEPT B và B EXCEPT A là những thứ khác nhau.
Ví dụ dưới đây nối name cho "sống ở Kyoto" và "lương từ 6.5 triệu trở lên" bên trong employee bằng INTERSECT, lấy ra những nhân viên thỏa cả hai (các hàng chung).
-- INTERSECT: nhân viên sống ở Osaka VÀ có lương từ 6000000 trở lên
SELECT name FROM employee WHERE city = 'Osaka'
INTERSECT
SELECT name FROM employee WHERE salary >= 6000000
ORDER BY name;
-- EXCEPT: nhân viên sống ở Osaka nhưng KHÔNG có lương từ 6000000 trở lên
SELECT name FROM employee WHERE city = 'Osaka'
EXCEPT
SELECT name FROM employee WHERE salary >= 6000000
ORDER BY name;
Phép toán tập hợp giữa các bảng khác nhau — employee và contractor
Phép toán tập hợp hoạt động không chỉ trong một bảng đơn mà còn giữa các kết quả lấy từ các bảng riêng rẽ.
Miễn là chúng tương thích UNION (khớp số cột và kiểu), các bảng có thể khác nhau.
Khi bạn muốn sắp xếp kết quả đã nối, hãy viết một ORDER BY duy nhất sau SELECT cuối cùng (nó áp dụng cho toàn bộ kết quả đã nối).
Nối name của bảng nhân viên employee và bảng nhà thầu contractor bằng INTERSECT cho phép bạn phát hiện những người xuất hiện ở cả hai với cùng tên.
Ví dụ dưới đây chỉ lấy cột name đơn và nối chúng bằng INTERSECT.
Vì cả name của hai bảng đều có Alice và Bob, 2 người được trả về dưới dạng các hàng chung.
-- các tên xuất hiện ở cả employee và contractor
SELECT name FROM employee
INTERSECT
SELECT name FROM contractor
ORDER BY name;
-- các tên trong contractor nhưng không trong employee (chỉ bên ngoài)
SELECT name FROM contractor
EXCEPT
SELECT name FROM employee
ORDER BY name;
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Khi nối hai SELECT bằng một phép toán tập hợp, điều kiện nào phải luôn được thỏa?
Câu 3Câu nào đúng về quan hệ giữa A EXCEPT B và B EXCEPT A?