2010-02-11 43 views
16

Câu hỏi đầu tiên của tôi về SO! Anywho ...SQL - Kết hợp nhiều truy vấn như truy vấn

Vẫn còn tương đối mới ở SQL vì vậy tôi nghĩ rằng tôi có thể thiếu một cái gì đó ở đây. Câu hỏi của tôi là tôi hiện đang có một bảng đầy đủ các số điện thoại. Tôi muốn có một truy vấn nơi tôi tìm kiếm các số điện thoại tương tự với danh sách tôi có. Ví dụ: tôi muốn tìm số điện thoại bắt đầu bằng '555123', '555321' và '555987'. Tôi biết bình thường nếu bạn có danh sách các số bạn chỉ có thể thực hiện truy vấn như

SELECT * 
    FROM phonenumbers 
WHERE number in ('5551234567', '5559876543', ....); 

Có cách nào để thực hiện việc này không? Chẳng hạn như

SELECT * 
    FROM phonenumbers 
WHERE number in like ('555123%', '555321%', '555987%'); //I know this doesn't actually work 

Thay vì phải làm điều này riêng

SELECT * 
    FROM phonenumbers 
WHERE number like '555123%' 
    or number like '555321%' 
    or number like '555987%'; //Which does work but takes a long time 

Hoặc là có một dễ dàng hơn để làm điều này mà tôi chỉ thiếu? Tôi đang sử dụng postgres, tôi không biết liệu có bất kỳ lệnh nào mà nó có thể giúp ích được không. Cảm ơn!

+1

Chào mừng bạn đến SO! Tôi đã gắn thẻ lại câu hỏi của bạn để làm rõ câu hỏi liên quan đến postgres – AdaTheDev

+0

Phiên bản Postgres nào? Âm thanh như một công việc cho regexes: http://www.postgresql.org/docs/8.3/static/functions-matching.html –

+0

'Làm việc nào nhưng mất một thời gian dài' - trừ khi bạn thay đổi bản chất của truy vấn, biểu diễn cú pháp khác nhau của cùng một thứ sẽ mất nhiều thời gian. Cột có được lập chỉ mục không? – MattH

Trả lời

25

Bạn có thể sử dụng SIMILAR TO và tách các thẻ với | ống '555123%|555321%|555987%'

ví dụ:

SELECT * 
FROM phonenumbers 
WHERE number SIMILAR TO '555123%|555321%|555987%' 
+1

Đây là khá nhiều những gì tôi đang tìm kiếm, cảm ơn! Làm việc cho những gì tôi cần. –

1

Có lẽ nếu tiền tố của bạn là tất cả cùng độ dài thì bạn có thể làm where RIGHT(number) in ('123456', '234456', 'etc', 'etc')

2

Tôi không nghĩ như vậy, nhưng bạn có thể tham gia phonenumbers trên bàn criteria chứa các giá trị bạn muốn kết hợp trên, tức là

JOIN criteria ON phonenumbers.number LIKE criteria.phonenumbers 

... có lẽ không giá trị nó cho một số ít các điều kiện, mặc dù

+0

Thực ra tôi có nhiều thứ hơn để tìm kiếm nhưng tôi nghĩ tôi nên giữ nó đơn giản chỉ với một vài con số. –

3

Giả sử tất cả các số của bạn không chứa các chữ cái:

SELECT number 
FROM (
     VALUES 
     ('555123'), 
     ('555321'), 
     ('555000') 
     ) prefixes (prefix) 
JOIN phonenumbers 
ON  number >= prefix 
     AND number < prefix || 'a' 

này sẽ sử dụng một chỉ mục trên phonenumbers, nếu có.

+0

Tôi đã nhìn thấy các truy vấn rất tốt từ người dùng của bạn, bạn đã học được những thứ ở đâu? Có cuốn sách bao gồm tất cả những cuốn sách này không? – Pentium10

+0

@ Pentium10: Tôi đã kiếm sống từ đó trong 12 năm. Tôi chưa bao giờ thấy một cuốn sách hay về nội dung cơ sở dữ liệu (chưa), gần như tất cả những điều này tôi đã tự tìm ra. – Quassnoi

+0

Bạn có một blog hoặc ý định viết một cuốn sách về những điều này? Tôi sẽ là một trong số những người mua. – Pentium10

0

Bạn cũng có thể dựa vào cụm từ thông dụng POSIX, xem phần 9.7.3 của official documentation.

Ví dụ:

SELECT * FROM foobar WHERE name ~ '12345|34567'; 

Điều quan trọng cần lưu ý là lĩnh vực name của bạn là của một loại chuỗi.

13

muộn để đảng, nhưng đối với sự thịnh vượng ... Bạn cũng có thể sử dụng một ANY(array expression)

SELECT * 
FROM phonenumbers 
WHERE number LIKE ANY(ARRAY['555123%', '555321%', '555987%'])