2011-02-07 33 views
86

Tengo una lista simple de ~ 25 palabras. Tengo un campo varchar en PostgreSQL, digamos que la lista es ['foo', 'bar', 'baz']. Quiero encontrar cualquier fila en mi mesa que tenga alguna de esas palabras. Esto funcionará, pero me gustaría algo más elegante.comodín de PostgreSQL LIKE para cualquiera de una lista de palabras

select * 
from table 
where (lower(value) like '%foo%' or lower(value) like '%bar%' or lower(value) like '%baz%') 

Respuesta

93

Puede utilizar operador Postgres' SIMILAR TO que soporta alternancias, es decir

select * from table where lower(value) similar to '%(foo|bar|baz)%'; 
+0

expresión regular puede acelerar este proceso un poco: http://dba.stackexchange.com/questions/10694/pattern-matching-with-like- similar-to-or-regular-expressions-in-postgresql – approxiblue

+0

¿Cómo lo sabes? la mayoría de la documentación que he leído dice que las expresiones regulares son más lentas y un LIKE% ... – DestyNova

+1

Según http://dba.stackexchange.com/a/10696/27757 'SIMILAR A' se traduce internamente a una búsqueda de expresiones regulares –

132

PostgreSQL también soporta completo POSIX regular expressions:

select * from table where value ~* 'foo|bar|baz'; 

El ~* es para un partido insensible caso, ~ mayúsculas y minúsculas.

Otra opción es utilizar ANY:

select * from table where value like any (array['%foo%', '%bar%', '%baz%']); 
select * from table where value ilike any (array['%foo%', '%bar%', '%baz%']); 

Se puede utilizar cualquier con cualquier operador que produce un valor lógico. Sospecho que las opciones de expresiones regulares serían más rápidas, pero CUALQUIERA es una herramienta útil para tener en tu caja de herramientas.

+0

Curiosamente , aunque ambos métodos son más elegantes que la solución de @chmullig (por lo que +1), al verificar al menos 3 opciones, se ejecutan de manera significativamente más lenta en tablas grandes (91,5 millones de registros en mi caso). Estaba viendo un aumento de tiempo de aproximadamente 2x cuando uso cualquiera de estos. ¿Alguna idea de por qué podría ser? – sage88

+0

@ sage88 No sé de sobra pero Erwin Brandstetter podría y agregando [índices de trigrama] (https://stackoverflow.com/a/13452528/479863) podría ayudar. –

1

En realidad no es un operador para que en PostgreSQL:

SELECT * 
FROM table 
WHERE lower(value) ~~ ANY('{%foo%,%bar%,%baz%}'); 
Cuestiones relacionadas