Trong 1 số trường hợp, chúng ta không thể viết 1 câu query duy nhất để lấy được kết quả mong muốn, mà phải viết nhiều câu lệnh trả về nhiều tập kết quả nhỏ. Khi đó, chúng ta có thể sử dụng toán tử tập hợp để kết hợp các kết quả lại với nhau, hoặc lọc ra kết quả mong muốn cuối cùng.

 

 

setoperators

 

Ta có 4 toán tử tập hợp bao gồm:

  • UNION: kết quả là tổng hợp các record từ 2 câu query sau khi đã loại bớt các record trùng lặp
  • UNION ALL: kết quả là tổng hợp các record từ 2 câu query nhưng không loại bớt các record trùng lặp
  • INTERSECT: kết quả là các record tồn tại ở cả 2 câu query
  • MINUS: kết quả là các record chỉ tồn tại ở câu query thứ nhất mà không tồn tại ở câu query thứ hai

 

Do kết quả được tổng hợp từ các câu query, khi sử dụng toán tử tập hợp cần lưu ý:

  • Số lượng column ở mỗi câu query phải bằng nhau. Do đó câu query nào thiếu column, ta có thể cho 1 column với biểu thức chứa giá trị mặc định vào vị trí thiếu
  • Kiểu dữ liệu ở mỗi column tương ứng phải tương tự nhau
  • Tên column trả về là tên các column ở câu query đầu tiên
  • Có thể dùng dấu () để xác định độ ưu tiên
  • ORDER BY chỉ được nằm ở câu query sau cùng, và nhận tên các column theo tên các column ở câu query đầu tiên

 

VD1: Liệt kê các vị trí công việc của employee_id 176 từ trước tới giờ. Ta phải query trong cả 2 table: employees & job_history

 

 

Có tới 2 dòng SA_REP. Thì ra ông này đã có thời gian làm SA_REP rồi nhảy qua làm SA_MAN rồi hiện tại quay lại làm SA_REP. Để kết quả hợp lý hơn, ta dùng UNION để cho ra kết quả không trùng lặp

 

 

VD2: Liệt kê tất cả những employee đã từng làm công việc hiện tại trong quá khứ (kiểu như ông 176 ở trên). Ta sẽ tìm dữ liệu trùng lặp ở 2 table employees & job_history bằng phép giao INTERSECT

 

 

VD3: Liệt kê những employee chưa đổi việc bao giờ. Tức là sẽ không có dữ liệu trong table job_history. Ta dùng phép MINUS

 

 

Mặc dù các phép như INTERSECT hay MINUS có thể viết bằng subquery, tuy nhiên khi gặp 1 số câu query phức tạp dài dòng, sử dụng các toán tử này có thể giúp câu query rõ ràng hơn. 

1 lưu ý nữa là phép UNION có sử dụng thêm bước sort để loại bớt các record trùng lặp, dẫn đến thời gian thực thi có thể lâu hơn nhiều phép UNION ALL nếu lượng dữ liệu lớn. Nếu được hãy sử dụng phép UNION ALL và xử lý lọc kết quả sau đó thay vì dùng UNION.