Sự khác biệt giữa toán tử IN
và ANY
trong PostgreSQL là gì?
Cơ chế hoạt động của cả hai dường như giống nhau. Bất cứ ai có thể giải thích điều này với một ví dụ?
Sự khác biệt giữa toán tử IN
và ANY
trong PostgreSQL là gì?
Cơ chế hoạt động của cả hai dường như giống nhau. Bất cứ ai có thể giải thích điều này với một ví dụ?
Câu trả lời:
(Không IN
phải ANY
là "toán tử". Một "cấu trúc" hoặc "phần tử cú pháp".)
Về mặt logic , trích dẫn sách hướng dẫn :
IN
tương đương với= ANY
.
Nhưng có hai biến thể cú pháp của IN
và hai biến thể của ANY
. Chi tiết:
IN
lấy một bộ tương đương với = ANY
lấy một bộ , như được minh họa ở đây:
Nhưng biến thể thứ hai của mỗi biến thể không tương đương với biến thể khác. Biến thể thứ hai của ANY
cấu trúc nhận một mảng (phải là một kiểu mảng thực tế), trong khi biến thể thứ hai IN
nhận danh sách các giá trị được phân tách bằng dấu phẩy . Điều này dẫn đến các hạn chế khác nhau trong việc chuyển các giá trị và cũng có thể dẫn đến các kế hoạch truy vấn khác nhau trong các trường hợp đặc biệt:
=any()
nhưng được sử dụng vớiin
ANY
linh hoạt hơnCấu ANY
trúc này linh hoạt hơn nhiều, vì nó có thể được kết hợp với nhiều toán tử khác nhau, không chỉ =
. Thí dụ:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Đối với một số lượng lớn giá trị, việc cung cấp một bộ quy mô tốt hơn cho từng:
Có liên quan:
"Tìm các hàng có id
trong mảng đã cho":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: "Tìm hàng nơi id
là không trong mảng":
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
Cả ba tương đương. Cái đầu tiên với hàm tạo mảng , hai cái còn lại với mảng ký tự . Kiểu dữ liệu có thể được lấy từ ngữ cảnh một cách rõ ràng. Ngoài ra, có thể yêu cầu một dàn diễn viên rõ ràng, như'{1,2}'::int[]
.
Các hàng với id IS NULL
không vượt qua một trong hai biểu thức này. Để bao gồm NULL
các giá trị bổ sung:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
sẽ luôn dẫn đến các hàng giống nhau SELECT * from mytable where id = ANY('{1, 2, 3}')
, ngay cả khi chúng có khả năng có các kế hoạch truy vấn khác nhau.
ANY
không thể kết hợp với !=
toán tử. Tôi không nghĩ rằng nó được ghi lại bằng tài liệu, nhưng select * from foo where id != ANY (ARRAY[1, 2])
không giống với select * from foo where id NOT IN (1, 2)
. Mặt khác, select * from foo where NOT (id = ANY (ARRAY[1, 2]))
hoạt động như mong đợi.
ANY
có thể kết hợp với !=
toán tử. Nhưng còn nhiều thứ hơn thế nữa. Tôi đã thêm một chương ở trên. (Lưu ý rằng <>
là các nhà điều hành trong SQL chuẩn - mặc dù !=
. Được chấp nhận cũng trong Postgres)
NULL
các giá trị hoạt động như thế nào? Sẽ WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
hoạt động tốt?
(id = ...) IS NOT TRUE
hoạt động vì id = ...
chỉ đánh giá TRUE
xem có khớp thực tế hay không. Kết quả FALSE
hoặc NULL
vượt qua bài kiểm tra của chúng tôi. Xem: stackoverflow.com/a/23767625/939860 . Các bài kiểm tra biểu thức đã thêm của bạn cho một thứ khác. Điều này sẽ tương đươngWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Có hai điểm rõ ràng, cũng như các điểm trong câu trả lời khác:
Chúng hoàn toàn tương đương khi sử dụng các truy vấn phụ:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
Mặt khác:
Chỉ IN
toán tử cho phép một danh sách đơn giản:
SELECT * FROM table
WHERE column IN(… , … , …);
Việc cho rằng chúng hoàn toàn giống nhau đã khiến tôi không khỏi ngạc nhiên khi quên rằng điều ANY
đó không hoạt động với danh sách.