Je také důležité pochopit, že ANY
není operátora ale konstrukt SQL, který lze použít pouze správně operátora. Více:
- Jak použít ANY místo IN v klauzuli WHERE s Rails?
LIKE
operátor – nebo přesněji:výraz , který je přepsán pomocí do ~~
operátor v Postgresu interně - očekává hodnotu doleva a vzor doprava. Neexistuje žádný COMMUTATOR
pro tento operátor (jako je tomu u jednoduchého operátoru rovnosti =
), takže Postgres nemůže obracet operandy.
Váš pokus:
select * from someTable where '%someInput%' LIKE ANY(someColum);
přehodil levý a pravý operand, takže '%someInput%'
je hodnota a prvky sloupce pole someColum
jsou považovány za vzory (což není to, co chcete).
by musí být ANY(someColum) LIKE '%someInput%'
- kromě toho, že to není možné s ANY
konstrukt, který je povolen pouze vpravo operátora. Zde narazíte na zátaras.
Související:
- Existuje způsob, jak užitečně indexovat textový sloupec obsahující vzory regulárních výrazů?
- Může PostgreSQL indexovat sloupce pole?
Můžete normalizovat svůj relační návrh a uložit prvky pole v samostatných řádcích v samostatné tabulce. V opačném případě unnest()
je řešení, jak jste již sami našli. Ale zatímco vás zajímá pouze existence alespoň jednoho shodného prvku, EXISTS
poddotaz bude nejefektivnější a zároveň se vyhne duplicitám ve výsledku – Postgres může zastavit vyhledávání, jakmile je nalezena první shoda:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Můžete chtít speciální znak v someInput
. Viz:
- Funkce Escape pro regulární výraz nebo vzory LIKE
Opatrně s negací (NOT LIKE ALL (...)
), když NULL
může být zapojen:
- Zkontrolujte, zda v poli Postgres existuje NULL