Det är också viktigt att förstå att ANY
är inte en operatör men en SQL-konstruktion som bara kan användas till höger av en operatör. Mer:
- Hur använder man ANY istället för IN i en WHERE-sats med Rails?
LIKE
operator - eller mer exakt:uttryck , som skrivs om med till ~~
operatör i Postgres internt - förväntar sig värdet till vänster och mönstret till höger. Det finns ingen COMMUTATOR
för den här operatorn (som det finns för den enkla likhetsoperatorn =
). ) så Postgres kan inte vända på operander.
Ditt försök:
select * from someTable where '%someInput%' LIKE ANY(someColum);
har vänt vänster och höger operand så '%someInput%'
är värdet och element i arraykolumnen someColum
tas för att vara mönster (vilket inte är vad du vill ha).
Det skulle måste vara ANY(someColum) LIKE '%someInput%'
- förutom att det inte är möjligt med ANY
konstruktion som endast är tillåten till höger av en operatör. Du kör på en vägspärr här.
Relaterat:
- Finns det något sätt att på ett användbart sätt indexera en textkolumn som innehåller regexmönster?
- Kan PostgreSQL indexera arraykolumner?
Du kan normalisera din relationsdesign och spara element av arrayen i separata rader i en separat tabell. Bortsett från det, unnest()
är lösningen, som du redan hittat själv. Men medan du bara är intresserad av att det finns minst ett matchande element, är en EXISTS
underfrågan kommer att vara mest effektiv samtidigt som du undviker dubbletter i resultatet - Postgres kan stoppa sökningen så snart den första matchningen hittas:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Du kanske vill escape specialtecken i someInput
. Se:
- Escape-funktion för reguljära uttryck eller LIKE-mönster
Var försiktig med negationen (NOT LIKE ALL (...)
) när NULL
kan vara involverade:
- Kontrollera om NULL finns i Postgres-arrayen