2014-09-01 16 views
11

Tôi thường sử dụng cú pháp integer = ANY(integer[]), nhưng bây giờ bất kỳ toán tử nào không hoạt động. Đây là lần đầu tiên tôi sử dụng nó để so sánh một vô hướng với một số nguyên được trả về từ CTE, nhưng tôi nghĩ rằng điều này sẽ không gây ra vấn đề.Toán tử không tồn tại: số nguyên = số nguyên [] trong truy vấn có ANY

truy vấn của tôi:

WITH bar AS (
    SELECT array_agg(b) AS bs 
    FROM foo 
    WHERE c < 3 
) 
SELECT a FROM foo WHERE b = ANY (SELECT bs FROM bar); 

Khi tôi chạy nó, nó throws lỗi sau:

ERROR: operator does not exist: integer = integer[]: WITH bar AS ( SELECT array_agg(b) AS bs FROM foo WHERE c < 3) SELECT a FROM foo WHERE b = ANY (SELECT bs FROM bar)

Chi tiết trong SQL Fiddle này.

Vì vậy, tôi đang làm gì sai?

Trả lời

11

Dựa trên phần thông báo lỗi operator does not exist: integer = integer[], dường như cột bs cần phải được unnest ed, để có được phía bên tay phải trở lại một integer nên toán tử so sánh có thể được tìm thấy:

WITH bar AS (
    SELECT array_agg(b) AS bs 
    FROM foo 
    WHERE c < 3 
) 
SELECT a 
FROM foo 
WHERE b = ANY (SELECT unnest(bs) FROM bar); 

Điều này dẫn đến kết quả:

A 
2 
3 

Do doc cho ANY function:

The right-hand side is a parenthesized subquery, which must return exactly one column. The left-hand expression is evaluated and compared to each row of the subquery result using the given operator, which must yield a Boolean result. The result of ANY is "true" if any true result is obtained. The result is "false" if no true result is found (including the case where the subquery returns no rows).

... lỗi có ý nghĩa, như các biểu hiện bên trái là một integer - cột b - trong khi các biểu hiện bên tay phải là một mảng của integer s, hoặc integer[], và vì vậy việc so sánh kết thúc có dạng integer = integer[], không có toán tử và do đó dẫn đến lỗi.

unnest nhập giá trị integer[] làm cho biểu thức bên trái và bên phải integer s và do đó so sánh có thể tiếp tục.

Đã sửa đổi SQL Fiddle.

Lưu ý: rằng cùng một hành vi được nhìn thấy khi sử dụng IN thay vì = ANY.

+8

Giải thích thêm dựa trên câu trả lời của bạn: Bởi vì '1 = BẤT CỨ (ARRAY [1,2,3])' là hợp pháp, nó là hợp lý cũng mong đợi '1 = BẤT CỨ (SELECT ARRAY [1,2,3]) 'là hợp pháp, nhưng không phải vì điều đó tạo ra sự mơ hồ về việc bạn có muốn' 1 = ARRAY [1,2,3] 'hay' 1 = 1 OR 1 = 2 HOẶC 1 = 3' và trình phân tích cú pháp không đủ thông minh để chỉ ra rằng chỉ một người có thể hợp pháp. Bạn có thể nói rằng bạn thực sự muốn dạng mảng BẤT CỨ với '1 = ANY ((SELECT ARRAY [1,2,3]) :: int [])' (mà tôi sẽ làm thay vì 'unnest'ing). –

+0

Ah, thú vị.Cảm ơn các chi tiết bổ sung. – khampson

+0

@CraigRinger: cảm ơn bạn! Câu trả lời của Ken đã giúp tôi làm thế nào để làm điều đó đúng, nhưng bình luận của bạn làm cho tôi hiểu tại sao truy vấn của tôi là sai. –

0

cột cần phải được unnest

VỚI thanh AS ( CHỌN array_agg (b) AS bs TỪ foo ĐÂU c) SELECT a TỪ foo ĐÂU b = BẤT CỨ (SELECT unnest (bs) thanh TỪ);

+1

Điều này khác với câu trả lời hiện tại như thế nào? –

0

mà không unnest

WITH bar AS (
    SELECT array_agg(b) AS bs 
    FROM foo 
    WHERE c < 3 
) 
SELECT a FROM foo WHERE (SELECT b = ANY (bs) FROM bar); 
Các vấn đề liên quan