Het is ook belangrijk om te begrijpen dat ANY
is niet een operator maar een SQL-constructie die alleen rechts kan worden gebruikt van een exploitant. Meer:
- Hoe gebruik je ANY in plaats van IN in een WHERE-clausule met Rails?
De LIKE
operator - of preciezer:uitdrukking , dat wordt herschreven met de ~~
operator intern in Postgres - verwacht de waarde naar links en het patroon naar rechts. Er is geen COMMUTATOR
voor deze operator (zoals er is voor de eenvoudige gelijkheidsoperator =
) zodat Postgres de operanden niet kan omdraaien.
Jouw poging:
select * from someTable where '%someInput%' LIKE ANY(someColum);
heeft de linker- en rechteroperand omgedraaid, dus '%someInput%'
is de waarde en elementen van de matrixkolom someColum
worden als patronen beschouwd (wat niet is wat je wilt).
Het zou moet ANY(someColum) LIKE '%someInput%'
. zijn - behalve dat dat niet mogelijk is met de ANY
constructie die alleen is toegestaan aan de rechts van een exploitant. Je raakt hier een wegversperring.
Gerelateerd:
- Is er een manier om een tekstkolom met regex-patronen op een nuttige manier te indexeren?
- Kunnen PostgreSQL matrixkolommen indexeren?
U kunt uw relationele ontwerp normaliseren en elementen opslaan van de array in aparte rijen in een aparte tabel. Behalve dat, unnest()
is de oplossing, zoals je zelf al hebt gevonden. Maar terwijl u alleen geïnteresseerd bent in het bestaan van ten minste één overeenkomend element, een EXISTS
subquery is het meest efficiënt en vermijdt duplicaten in het resultaat - Postgres kan het zoeken stoppen zodra de eerste overeenkomst is gevonden:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Misschien wilt u speciale tekens in someInput
. Zie:
- Escape-functie voor reguliere expressies of LIKE-patronen
Pas op met de ontkenning (NOT LIKE ALL (...)
) wanneer NULL
kan betrokken zijn:
- Controleer of NULL bestaat in Postgres-array