Também é importante entender que
ANY
é não um operador mas uma construção SQL que só pode ser usada para a direita de um operador. Mais:- Como usar ANY em vez de IN em uma cláusula WHERE com Rails?
O
LIKE
operador - ou mais precisamente:expressão , que é reescrito com o ~~
operador no Postgres internamente - espera o valor para a esquerda e o padrão Para a direita. Não há COMMUTATOR
para este operador (como existe para o operador de igualdade simples =
) para que o Postgres não possa inverter os operandos. Sua tentativa:
select * from someTable where '%someInput%' LIKE ANY(someColum);
inverteu os operandos esquerdo e direito, então
'%someInput%'
é o valor e elementos da coluna array someColum
são considerados padrões (o que não é o que você quer). Ele seria tem que ser
ANY(someColum) LIKE '%someInput%'
- exceto que não é possível com o ANY
construção que só é permitida à direita de um operador. Você está batendo em um bloqueio de estrada aqui. Relacionado:
- Existe uma maneira útil de indexar uma coluna de texto contendo padrões regex?
- O PostgreSQL pode indexar colunas de array?
Você pode normalizar seu design relacional e salvar elementos da matriz em linhas separadas em uma tabela separada. Tirando isso,
unnest()
é a solução, como você já se encontrou. Mas enquanto você está interessado apenas na existência de pelo menos um elemento correspondente, um EXISTS
subconsulta será mais eficiente evitando duplicatas no resultado - Postgres pode parar a busca assim que a primeira correspondência for encontrada:SELECT *
FROM tbl
WHERE EXISTS (
SELECT -- can be empty
FROM unnest(someColum) elem
WHERE elem LIKE '%someInput%'
);
Você pode querer escapar caracteres especiais em
someInput
. Ver:- Função Escape para expressão regular ou padrões LIKE
Cuidado com a negação (
NOT LIKE ALL (...)
) quando NULL
pode estar envolvido:- Verifique se NULL existe no array Postgres