Ważne jest również, aby zrozumieć, że ANY
jest nie operator ale konstrukcja SQL, której można używać tylko w prawo operatora. Więcej:
- Jak używać ANY zamiast IN w klauzuli WHERE w Railsach?
LIKE
operator - a dokładniej:wyrażenie , który jest przepisany z do ~~
operator w Postgresie wewnętrznie - oczekuje wartości po lewej stronie i wzór w prawo. Nie ma COMMUTATOR
dla tego operatora (tak jak w przypadku prostego operatora równości =
), więc Postgres nie może odwracać operandów.
Twoja próba:
select * from someTable where '%someInput%' LIKE ANY(someColum);
zamienił lewy i prawy operand, więc '%someInput%'
jest wartością i elementy kolumny tablicy someColum
są uważane za wzorce (co nie jest tym, czego chcesz).
byłoby musi być ANY(someColum) LIKE '%someInput%'
- z wyjątkiem tego, że nie jest to możliwe w przypadku ANY
konstrukcja, która jest dozwolona tylko po prawej operatora. Trafiasz na blokadę drogi.
Powiązane:
- Czy istnieje sposób na przydatne indeksowanie kolumny tekstowej zawierającej wzorce wyrażeń regularnych?
- Czy PostgreSQL może indeksować kolumny tablicy?
Możesz znormalizować swój projekt relacyjny i zapisać elementy tablicy w osobnych wierszach w osobnej tabeli. Poza tym unnest()
jest rozwiązaniem, jakie już znalazłeś. Ale chociaż interesuje Cię tylko istnienie co najmniej jednego pasującego elementu, EXISTS
podzapytanie będzie najskuteczniejsze, unikając duplikatów w wynikach — Postgres może zatrzymać wyszukiwanie zaraz po znalezieniu pierwszego dopasowania:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Możesz chcieć uciec przed znakiem specjalnym w someInput
. Zobacz:
- Funkcja wyjścia dla wyrażeń regularnych lub wzorców LIKE
Ostrożnie z negacją (NOT LIKE ALL (...)
) gdy NULL
może być zaangażowany:
- Sprawdź, czy w tablicy Postgres istnieje NULL