Kelimelerin herhangi bir listesi için PostgreSQL joker karakter LIKE


156

~ 25 kelimelik basit bir listem var. PostgreSQL'de bir varchar alanım var, diyelim ki liste bu ['foo', 'bar', 'baz']. Masamda bu kelimelerin herhangi birine sahip herhangi bir satır bulmak istiyorum. Bu işe yarayacak, ama daha zarif bir şey istiyorum.

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

Yanıtlar:


166

Postgres'in SIMILAR TOalternatifleri destekleyen operatörünü kullanabilirsiniz.

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

1
Regex bunu biraz hızlandırabilir: dba.stackexchange.com/questions/10694/…
approxiblue

Nasıl biliyorsun ? Okuduğum belgelerin çoğu normal ifadenin daha yavaş ve% LIKE olduğunu söylüyor ...
DestyNova

5
Dba.stackexchange.com/a/10696/27757'ye göre SIMILAR TOdahili olarak normal ifade aramasına çevrilmiştir
Mark K Cowan

Ben lower()ilk önce her bir dize küçük harf dönüştürmek için kullanmanın etkisiz olduğunu düşünüyorum , bu sadece büyük-küçük harf duyarsız bir maç daha pahalı
gilad mayani

229

PostgreSQL ayrıca tam POSIX düzenli ifadelerini de destekler :

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

Büyük / ~*küçük harf duyarlı olmayan bir eşleşme içindir, ~büyük / küçük harfe duyarlıdır.

Başka bir seçenek HERHANGİ BİRİ kullanmaktır :

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

Herhangi bir boole veren herhangi bir operatörle HERHANGİ BİRİ kullanabilirsiniz. Normal ifade seçeneklerinin daha hızlı olacağından şüpheleniyorum, ancak HERHANGİ bir araç kutunuzda olması yararlı bir araçtır.


İlginç bir şekilde, bu yöntemlerin her ikisi de @chmullig'in çözümünden (yani +1) daha zarif olsa da, en az 3 seçeneği kontrol ederken, büyük tablolarda (benim durumumda 91.5 milyon kayıt) önemli ölçüde yavaş çalışıyorlar. Bunlardan herhangi birini kullanırken yaklaşık 2 kat bir zaman artışı görüyordum. Bunun neden olabileceğine dair bir fikrin var mı?
sage88

@ sage88 Başımın üstünü bilmiyorum ama Erwin Brandstetter yardımcı olabilir ve trigram indeksleri eklemek yardımcı olabilir.
mu çok kısa

13

Aslında PostgreSQL'de bunun için bir operatör var:

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


Yani olabilir ilike ile kullanılabilir herhangi aynı şekilde & dizide? Süslü regex gerekmiyorsa bu temiz görünüyor. Yoksa yine de dahili olarak normal ifadeye çevrilecek mi?
mlt

@mlt Bu iyi bir soru, dokümanı okumak açık bir cevap vermiyor. SIMILAR TONormal İfade'ye dönüşürse, ~operatör POSIX Düzenli İfade anlamına gelir, ancak bu açık değildir LIKE.
jlandercy

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.