Chương 9. Hàm và toán tử
9.20. Biểu thức truy vấn con
Phần này mô tả các biểu thức truy vấn con tuân thủ SQL có sẵn trong PostgreSQL. Tất cả các mẫu biểu thức được ghi chép trong phần này trả về các kết quả Boolean (đúng/sai – true/false).
9.20.1. EXISTS
EXISTS (subquery)
Đối số của EXISTS là một lệnh tùy ý SELECT, hoặc một truy vấn con. Truy vấn con được đánh giá để xác định liệu nó có trả về bất kỳ hàng nào hay không. Nếu nó trả về ít nhất 1 hàng, thì kết quả của
EXISTS là đúng “true”; Nếu truy vấn phụ không trả về hàng nào, thì kết quả của EXISTS là sai “false”.
Truy vấn con có thể tham chiếu tới các biến từ truy vấn bao quanh, nó sẽ hành động như các hằng số trong bất kỳ một đánh giá nào của truy vấn con đó.
Truy vấn con thường sẽ chỉ được thực thi đủ lâu để xác định liệu có ít nhất một hàng được trả về hay không, chứ không phải trên đường hoàn tất. Là không khôn ngoan để viết một truy vấn con mà có các hiệu ứng phụ (như gọi các hàm tuần tự); liệu các hiệu ứng phụ xảy ra có là không thể đoán trước được hay không.
Vì kết quả chỉ phụ thuộc vào liệu có bất kỳ hàng nào được trả về hay không, và không dựa vào các nội dung của các hàng đó, danh sách đầu ra của truy vấn con đó thường là quan trọng. Một qui ước lập trình chung là phải viết tất cả các kiểm thử EXISTS ở dạng EXISTS(SELECT 1 WHERE ...). Tuy nhiên,
có các ngoại lệ cho qui tắc này, như các truy vấn con mà sử dụng INTERSECT.
Ví dụ đơn giản này giống như một kết nối bên trong ở col2, nhưng nó tạo ra nhiều nhất một hàng đầu ra cho từng hàng của tab1, thậm chí nếu có vài hàng của tab2 khớp:
SELECT col1 FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
9.20.2. IN
expression IN (subquery)
Phía bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác một cột.
Biểu thức bên tay trái được đánh giá và được so sánh với từng hàng kết quả của truy vấn con đó.
Kết quả của IN là đúng “true” nếu bất kỳ hàng của truy vấn con nào bằng được tìm thấy. Kết quả là sai “false” nếu không hàng nào bằng được thấy (bao gồm cả trường hợp nơi mà truy vấn con đó không trả về hàng nào cả).
Lưu ý rằng nếu biểu thức bên tay trái cho ra null, hoặc nếu không có các giá trị bằng nào bên tay phải và ít nhất một hàng bên tay phải có null, thì kết quả của cấu trúc IN sẽ là null, chứ không phải là false. Điều này là tuân theo với các qui tắc thông thường của SQL cho các kết hợp Boolean của các giá trị null.
Như với EXISTS, không khôn ngoan để giả thiết rằng truy vấn con đó sẽ được đánh giá hoàn chỉnh.
row_constructor IN (subquery)
Phía bên tay trái của mẫu này của IN là một cấu trúc hàng, như được mô tả trong Phần 4.2.12. Phần bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác càng nhiều cột như có các biểu thức ở hàng bên tay trái. Các biểu thức bên tay trái được đánh giá và được so sánh từng hàng một đối với kết quả của truy vấn con. Kết quả của IN là “true” nếu bất kỳ hàng của truy vấn con bằng nhau nào được thấy. Kết quả là “false” nếu không hàng bằng nhau nào được thấy (bao gồm cả trường hợp nơi mà truy vấn con không trả về hàng nào).
Như thường lệ, các giá trị null trong các hàng được kết hợp theo các qui tắc thông thường của các biểu thức Boolean của SQL. Hai hàng được xem là bằng nhau nếu tất cả các thành viên tương ứng của chúng là không null và bằng nhau; các hàng không bằng nhau nếu bất kỳ các thành viên tương ứng nào là không null và không bằng nhau; nếu không thì kết quả của sự so sánh hàng đó là không rõ (null). Nếu tất cả các kết quả theo hàng hoặc không bằng nhau hoặc là null, với ít nhất một kết quả null, thì kết quả của IN là null.
9.20.3. NOT IN
expression NOT IN (subquery)
Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác 1 cột. Biểu thức bên tay trái được đánh giá và được so sánh với từng hàng kết quả của truy vấn con đó. Kết quả của
NOT IN là “true” nếu chỉ các hàng không bằng nhau của truy vấn con được thấy (bao gồm cả trường
hợp nơi mà truy vấn con đó không trả về hàng nào). Kết quả là “false” nếu bất kỳ hàng bằng nhau nào được tìm thấy.
Lưu ý rằng nếu biểu thức bên tay trái cho null, hoặc nếu không có các giá trị bằng nhau bên tay phải và ít nhất một hàng bên tay phải cho null, thì kết quả của cấu trúc NOT IN sẽ là null, chứ không phải là true. Điều này là tuân theo với các qui tắc thông thường của SQL cho các kết hợp Boolean của các giá trị null.
Như với EXISTS, là không khôn ngoan để giả thiết rằng truy vấn con sẽ được đánh giá hoàn chỉnh.
row_constructor NOT IN (subquery)
Bên tay trái của mẫu này của NOT IN là một cấu trúc hàng, như được mô tả trong Phần 4.2.12. Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác càng nhiều cột như có các biểu thức ở hàng bên tay trái. Các biểu thức bên tay trái được đánh giá và được so sánh với từng hàng của kết quả truy vấn con. Kết quả của NOT IN là “true” nếu chỉ các hàng truy vấn con không bằng nhau được tìm thấy (bao gồm trường hợp nơi mà truy vấn con đó không trả về hàng nào). Kết quả là “false” nếu bất kỳ hàng bằng nhau nào được tìm thấy.
Như thường lệ, các giá trị null trong các hàng được kết hợp theo các qui tắc thông thường của các biểu thức Boolean SQL. Hai hàng được xem là bằng nhau nếu tất cả các thành viên tương ứng của chúng là không null và bằng nhau; các hàng là không bằng nhau nếu bất kỳ các thành viên tương ứng nào là không null và không bằng nhau; nếu không thì kết quả của so sánh hàng đó là không rõ (null). Nếu tất cả các kết quả theo hàng hoặc không bằng nhau hoặc là null, với ít nhất một kết quả null, thì sau đó kết quả của NOT IN là null.
9.20.4. ANY/SOME
expression operator ANY (subquery) expression operator SOME (subquery)
Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác một cột. Biểu thức bên tay trái được đánh giá và được so sánh hàng khôn ngoan theo từng hàng kết quả của truy vấn con bằng việc sử dụng operator được đưa ra, nó phải cho một kết quả Boolean. Kết quả của ANY
là “true” nếu bất kỳ kết quả true nào có được. Kết quả là “false” nếu không kết quả true nào được thấy (bao gồm trường hợp nơi mà truy vấn con không trả về hàng nào).
SOME là một đồng nghĩa với ANY. IN là tương đương với = ANY.
Lưu ý là nếu không có thành công và ít nhất một hàng bên tay phải có null cho kết quả của toán tử đó, thì kết quả của cấu trúc ANY sẽ là null, không phải là false. Điều này là tuân theo với các qui tắc thông thường của SQL đối với các kết hợp Boolean của các giá trị null.
Như với EXISTS, là không khôn ngoan để giả thiết rằng truy vấn con sẽ được đánh giá hoàn chỉnh.
row_constructor operator ANY (subquery) row_constructor operator SOME (subquery)
Bên tay trái của mẫu này của ANY là một cấu trúc hàng, như được mô tả trong Phần 4.2.12. Bên tay
phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác càng nhiều cột như có các biểu thức trong hàng bên tay trái càng tốt. Các biểu thức bên tay trái được đánh giá và được so sánh hàng khôn ngoan theo từng hàng kết quả của truy vấn con đó, bằng việc sử dụng operator được đưa ra. Kết quả của ANY là “true” nếu sự so sánh đó trả về true cho bất kỳ hàng truy vấn con nào.
Kết quả là “false” nếu so sánh đó trả về false cho từng hàng của truy vấn con đó (bao gồm cả trường hợp nơi mà truy vấn con đó không trả về hàng nào). Kết quả là NULL nếu so sánh đó không trả về true cho bất kỳ hàng nào, và nó trả về NULL cho ít nhất một hàng.
Xem Phần 9.21.5 về các chi tiết về ý nghĩa của một so sánh hàng khôn ngoan.
9.20.5. ALL
expression operator ALL (subquery)
Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác 1 cột. Biểu thức bên tay trái được đánh giá và được so sánh tới từng hàng kết quả của truy vấn con bằng việc sử dụng operator được đưa ra, nó phải cho một kết quả Boolean. Kết quả của ALL là “true” nếu tất cả các hàng cho true (bao gồm cả trường hợp nơi mà truy vấn con đó không trả về hàng nào). Các kết quả là “false” nếu bất kỳ kết quả false nào được tìm thấy. Kết quả là NULL nếu so sánh đó không trả về false cho bất kỳ hàng nào, và nó trả về NULL cho ít nhất một hàng.
NOT IN là tương đương với <> ALL.
Như với EXISTS, là không khôn ngoan để giả thiết rằng truy vấn con sẽ được đánh giá hoàn chỉnh.
row_constructor operator ALL (subquery)
Bên tay trái của mẫu này của ALL là một cấu trúc hàng, như được mô tả trong Phần 4.2.12. Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác càng nhiều cột như có các biểu thức ở hàng bên tay trái càng tốt. Các biểu thức bên tay trái được đánh giá và được so sánh hàng khôn ngoan cho từng hàng kết quả của truy vấn con, bằng việc sử dụng operator được đưa ra.
Kết quả của ALL là “true” nếu so sánh đó trả về true cho tất cả các hàng của truy vấn con đó (bao gồm cả trường hợp nơi mà truy vấn con đó không trả về hàng nào). Kết quả là “false” nếu so sánh đó trả về false cho bất kỳ hàng nào của truy vấn con. Kết quả là NULL nếu so sánh đó không trả về false cho bất ký hàng truy vấn con nào, và nó trả về NULL cho ít nhất một hàng.
Xem Phần 9.21.5 để có các chi tiết về ý nghĩa của một so sánh hàng khôn ngoan.
9.20.6. So sánh hàng khôn ngoan
row_constructor operator (subquery)
Bên tay trái là một cấu trúc hàng, như được mô tả trong Phần 4.2.12. Bên tay phải là một truy vấn con trong các dấu ngoặc đơn, nó phải trả về chính xác càng nhiều cột như có các biểu thức ở hàng bên tay trái càng tốt. Hơn nữa, truy vấn con không thể trả về nhiều hơn 1 hàng. (Nếu nó không trả về hàng nào, thì kết quả được lấy là null). Bên tay trái được đánh giá và được so sánh hàng khôn ngoan cho từng hàng kết quả của truy vấn con duy nhất.
Xem Phần 9.21.5 để có các chi tiết về ý nghĩa của một so sánh hàng khôn ngoan.