Cũng cần hiểu rằng ANY
là không một nhà điều hành nhưng một cấu trúc SQL chỉ có thể được sử dụng cho bên phải của một nhà điều hành. Thêm:
- Làm cách nào để sử dụng ANY thay vì IN trong mệnh đề WHERE với Rails?
LIKE
toán tử - hay chính xác hơn: biểu thức , được viết lại bằng ~~
nhà điều hành trong nội bộ Postgres - mong đợi giá trị ở bên trái và mẫu rẽ phải. Không có COMMUTATOR
đối với toán tử này (giống như đối với toán tử bình đẳng đơn giản =
) vì vậy Postgres không thể lật các toán hạng xung quanh.
Nỗ lực của bạn:
select * from someTable where '%someInput%' LIKE ANY(someColum);
đã lật toán hạng trái và phải nên '%someInput%'
là giá trị và các phần tử của cột mảng someColum
được coi là các khuôn mẫu (đó không phải là điều bạn muốn).
Nó sẽ phải là ANY(someColum) LIKE '%someInput%'
- ngoại trừ điều đó là không thể với ANY
cấu trúc chỉ được phép ở bên phải của một nhà điều hành. Bạn đang gặp một đoạn đường ở đây.
Có liên quan:
- Có cách nào để lập chỉ mục hữu ích cột văn bản chứa các mẫu regex không?
- PostgreSQL có thể lập chỉ mục các cột mảng không?
Bạn có thể chuẩn hóa thiết kế quan hệ của mình và lưu các phần tử của mảng trong các hàng riêng biệt trong một bảng riêng biệt. Cấm điều đó, unnest()
là giải pháp, như bạn đã tìm thấy chính mình. Nhưng trong khi bạn chỉ quan tâm đến sự tồn tại của ít nhất một phần tử phù hợp, thì EXISTS
truy vấn con sẽ hiệu quả nhất trong khi tránh trùng lặp trong kết quả - Postgres có thể dừng tìm kiếm ngay khi tìm thấy kết quả phù hợp đầu tiên:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Bạn có thể muốn thoát ký tự đặc biệt trong someInput
. Xem:
- Hàm Escape cho biểu thức chính quy hoặc mẫu LIKE
Cẩn thận với phủ định (NOT LIKE ALL (...)
) khi NULL
có thể tham gia:
- Kiểm tra xem NULL có tồn tại trong mảng Postgres không