2011-02-07 9 views
86

Ho una semplice lista di ~ 25 parole. Ho un campo varchar in PostgreSQL, diciamo che la lista è ['foo', 'bar', 'baz']. Voglio trovare qualsiasi riga nel mio tavolo che abbia una di quelle parole. Questo funzionerà, ma mi piacerebbe qualcosa di più elegante.jolly PostgreSQL come per qualsiasi elenco di parole

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

risposta

93

È possibile utilizzare Postgres' SIMILAR TO operatore che sostiene alternanze, vale a dire

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

Regex potrebbe accelerare l'operazione un po ': http://dba.stackexchange.com/questions/10694/pattern-matching-with-like- espressioni simili a regolari: in postgresql – approxiblue

+0

Come fai a saperlo? la maggior parte della documentazione che ho letto dice che le regex sono più lente e un LIKE% ... – DestyNova

+1

Secondo http://dba.stackexchange.com/a/10696/27757 'SIMILE A' è internamente tradotto in una ricerca regolare –

132

PostgreSQL supporta anche pieno POSIX regular expressions:

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

Il ~* è per una tra maiuscole e minuscole, ~ è case sensitive.

Un'altra opzione è quella di utilizzare ANY:

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

è possibile utilizzare qualsiasi con qualsiasi operatore che produce un valore booleano. Sospetto che le opzioni regex siano più veloci ma QUALSIASI è uno strumento utile da avere nella tua casella degli strumenti.

+0

Interessante , mentre entrambi questi metodi sono più eleganti della soluzione di @chmullig (quindi +1), quando si controllano almeno 3 opzioni, vengono eseguite molto più lentamente su tabelle grandi (91,5 milioni di record nel mio caso). Stavo vedendo un aumento di tempo di circa 2x quando si utilizza uno di questi. Qualche idea sul perché potrebbe essere? – sage88

+0

@ sage88 Non lo so, ma Erwin Brandstetter potrebbe e aggiungere [indici trigramma] (https://stackoverflow.com/a/13452528/479863) potrebbe aiutare. –

1

In realtà c'è un operatore per quella in PostgreSQL:

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