2011-02-07 31 views
86

Tôi có một danh sách đơn giản gồm ~ 25 từ. Tôi có một trường varchar trong PostgreSQL, giả sử danh sách đó là ['foo', 'bar', 'baz']. Tôi muốn tìm bất kỳ hàng nào trong bảng có bất kỳ từ nào trong số đó. Điều này sẽ làm việc, nhưng tôi muốn một cái gì đó thanh lịch hơn.Ký tự đại diện PostgreSQL THÍCH cho bất kỳ danh sách từ nào

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

Trả lời

93

Bạn có thể sử dụng Postgres' SIMILAR TO điều hành hỗ trợ alternations, ví dụ:

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

Regex có thể tăng tốc độ này lên một chút: http://dba.stackexchange.com/questions/10694/pattern-matching-with-like- tương tự-to-or-regular-expressions-in-postgresql – approxiblue

+0

Làm sao bạn biết? hầu hết tài liệu tôi đã đọc nói rằng regex chậm hơn và LIKE% ... – DestyNova

+1

Theo http://dba.stackexchange.com/a/10696/27757 'SIMILAR TO' được dịch nội bộ sang tìm kiếm regex –

132

PostgreSQL cũng hỗ trợ đầy đủ POSIX regular expressions:

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

Các ~* là dành cho một trường hợp trận đấu nhạy cảm, ~ là trường hợp nhạy cảm.

Một lựa chọn khác là sử dụng ANY:

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

Bạn có thể sử dụng bất kỳ với bất kỳ nhà điều hành mà mang lại một boolean. Tôi nghi ngờ rằng các tùy chọn regex sẽ nhanh hơn nhưng BẤT K is là một công cụ hữu ích để có trong hộp công cụ của bạn.

+0

Thú vị , trong khi cả hai phương pháp này thanh lịch hơn giải pháp @chmullig (do đó +1), khi kiểm tra 3 tùy chọn ít nhất, chúng thực thi chậm hơn đáng kể trên các bảng lớn (91,5 triệu bản ghi trong trường hợp của tôi). Tôi đã nhìn thấy một sự gia tăng thời gian khoảng 2x khi sử dụng một trong hai. Bất kỳ ý tưởng tại sao có thể? – sage88

+0

@ sage88 Tôi không biết ngoài đầu của tôi nhưng Erwin Brandstetter có thể và thêm [chỉ số trigram] (https://stackoverflow.com/a/13452528/479863) có thể hữu ích. –

1

Trên thực tế có một nhà điều hành cho rằng trong PostgreSQL:

SELECT * 
FROM table 
WHERE lower(value) ~~ ANY('{%foo%,%bar%,%baz%}'); 
Các vấn đề liên quan