PostgreSQL comodín COMO para cualquiera de una lista de palabras


156

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 tabla que tenga alguna de esas palabras. Esto funcionará, pero me gustaría algo más elegante.

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

Respuestas:


166

Puede usar el SIMILAR TOoperador de Postgres que admite alternancias, es decir

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

1
Regex podría acelerar esto un poco: dba.stackexchange.com/questions/10694/…
aproximadamente el

Como lo sabes ? la mayor parte de la documentación que he leído dice que las expresiones regulares son más lentas y un% ME GUSTA ...
DestyNova

55
De acuerdo con dba.stackexchange.com/a/10696/27757 SIMILAR TO se traduce internamente a una búsqueda de expresiones regulares
Mark K Cowan

Creo que el uso lower()es ineficaz porque primero se convertirá cada cadena a minúsculas, lo que es más costoso que solamente un partido entre mayúsculas y minúsculas
Gilad Mayani

229

PostgreSQL también admite expresiones regulares POSIX completas :

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

El ~*es para una coincidencia entre mayúsculas y minúsculas, ~es sensible a mayúsculas y minúsculas

Otra opción es usar CUALQUIERA :

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

Puede usar CUALQUIERA con cualquier operador que produzca un valor booleano. Sospecho que las opciones de expresiones regulares serían más rápidas, pero CUALQUIERA es una herramienta útil para tener en su caja de herramientas.


Curiosamente, si bien ambos métodos son más elegantes que la solución de @chmullig (por lo tanto, +1), al marcar 3 opciones al menos, se ejecutan significativamente más lento en tablas grandes (91,5 millones de registros en mi caso). Estaba viendo un aumento de tiempo de aproximadamente 2 veces al usar cualquiera de estos. ¿Alguna idea de por qué podría ser eso?
sage88

@ sage88 No lo sé, pero podría ayudar Erwin Brandstetter y agregar índices de trigrama .
mu es demasiado corto el

13

En realidad, hay un operador para eso en PostgreSQL:

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


Así puede iLike usarse con cualquier y variedad de la misma manera? Esto se ve limpio si no hay necesidad de expresiones regulares sofisticadas. ¿O se traducirá a regex internamente de todos modos?
mlt

@mlt Esa es una buena pregunta, leer el documento no proporciona una respuesta explícita. SIMILAR TOse convierte en expresión regular, el ~operador representa la expresión regular POSIX, pero esto no está claro LIKE.
jlandercy

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.