Det er også vigtigt at forstå, at ANY
er ikke en operatør men en SQL-konstruktion, der kun kan bruges til højre af en operatør. Mere:
- Hvordan bruger man ANY i stedet for IN i en WHERE-sætning med Rails?
LIKE
operator - eller mere præcist:udtryk , der er omskrevet med til ~~
operatør i Postgres internt - forventer værdien til venstre og mønsteret til højre. Der er ingen COMMUTATOR
for denne operator (som der er for den simple lighedsoperator =
) så Postgres kan ikke vende operander rundt.
Dit forsøg:
select * from someTable where '%someInput%' LIKE ANY(someColum);
har vendt operand til venstre og højre, så '%someInput%'
er værdien og elementer i array-kolonnen someColum
tages for at være mønstre (hvilket ikke er, hvad du ønsker).
Det ville skal være ANY(someColum) LIKE '%someInput%'
- bortset fra at det ikke er muligt med ANY
konstruktion, som kun er tilladt til højre af en operatør. Du rammer en vejspærring her.
Relateret:
- Er der en nyttig måde at indeksere en tekstkolonne, der indeholder regex-mønstre?
- Kan PostgreSQL indeksere array-kolonner?
Du kan normalisere dit relationelle design og gemme elementer af arrayet i separate rækker i en separat tabel. Bortset fra det, unnest()
er løsningen, som du allerede har fundet dig selv. Men mens du kun er interesseret i eksistensen af mindst ét matchende element, er en EXISTS
underforespørgsel vil være mest effektiv, mens du undgår dubletter i resultatet - Postgres kan stoppe søgningen, så snart det første match er fundet:
SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Du vil måske undslippe specialtegn i someInput
. Se:
- Escape-funktion til regulære udtryk eller LIKE-mønstre
Forsigtig med negationen (NOT LIKE ALL (...)
) når NULL
kan involveres:
- Tjek, om NULL findes i Postgres-arrayet