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