Sự khác biệt giữa toán tử INvà ANYtrong 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ử INvà ANYtrong 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 INphải ANYlà "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 :
INtương đương với= ANY.
Nhưng có hai biến thể cú pháp của INvà hai biến thể của ANY. Chi tiết:
IN lấy một bộ tương đương với = ANYlấ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 ANYcấ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 INnhậ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ớiinANY linh hoạt hơnCấu ANYtrú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ó idtrong mảng đã cho":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: "Tìm hàng nơi idlà 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 NULLkhông vượt qua một trong hai biểu thức này. Để bao gồm NULLcá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.
ANYcó 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)
NULLcá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 TRUEhoạt động vì id = ...chỉ đánh giá TRUExem có khớp thực tế hay không. Kết quả FALSEhoặc NULLvượ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ỉ INtoá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.