2012-11-17 23 views
11

Hãy nói rằng tôi có một bảng, email_phone_notes trông như thế này:MySQL: Làm thế nào để số lượng lớn CHỌN hàng với nhiều cặp trong mệnh đề WHERE

+-----------------------+--------------+------+-----+---------+-------+ 
| Field     | Type   | Null | Key | Default | Extra | 
+-----------------------+--------------+------+-----+---------+-------+ 
| email     | varchar  | NO | PRI | NULL |  | 
| phone     | varchar  | NO | PRI | NULL |  | 
| notes     | text   | NO |  | 0  |  | 
+-----------------------+--------------+------+-----+---------+-------+ 

Vì vậy, mỗi sự kết hợp email/điện thoại là duy nhất, nhưng bạn có thể có một số địa chỉ email có số điện thoại khác nhau và ngược lại. Đây là một chút contrived nhưng nó phản ánh kịch bản của tôi.

Tôi muốn làm một truy vấn như thế này:

SELECT * FROM email_phone_notes  WHERE email = '[email protected]' AND phone = '555-1212'; 

Nhưng, tôi muốn làm nhiều cặp cùng một lúc vì vậy tôi không cần phải thực hiện một số SELECT truy vấn. Điều quan trọng là phải giữ các cặp với nhau bởi vì tôi không muốn trả lại một sự kết hợp điện thoại/email không rõ ràng đã không được yêu cầu.

Tôi có thể làm một cái gì đó như thế này, nhưng đối với khả năng vài trăm giá trị truy vấn sẽ thực sự dài.

SELECT * FROM email_phone_notes WHERE ( 
    (email='[email protected]' && phone='555-1212') || 
    (email='[email protected]' && phone='888-1212') || 
    ... 

Có giải pháp thanh lịch hơn hay tôi nên gắn bó với điều này? Cảm ơn!

Trả lời

21

Nếu bạn sau khi SQL thanh lịch, bạn có thể sử dụng nhà thầu hàng:

SELECT * FROM email_phone_notes WHERE (email, phone) IN (
    ('[email protected]' , '555-1212'), 
    ('[email protected]', '888-1212') 
    -- etc. 
); 

Tuy nhiên, đó không phải là ở tất cả các chỉ số thân thiện và sẽ không được khuyến khích trên bàn của bất kỳ kích thước đáng kể. Thay vào đó, bạn có thể hiện thực một bảng với cặp mong muốn của bạn và tham gia rằng với bảng của bạn:

SELECT * FROM email_phone_notes NATURAL JOIN (
    SELECT '[email protected]' AS email, '555-1212' AS phone 
UNION ALL 
    SELECT '[email protected]', '888-1212' 
-- etc. 
) t; 

Hoặc khác trước động điền vào (tạm thời) Bảng:

CREATE TEMPORARY TABLE foo (PRIMARY KEY (email, phone)) Engine=MEMORY 
    SELECT email, phone FROM email_phone_notes WHERE FALSE 
; 

INSERT INTO foo 
    (email, phone) 
VALUES 
    ('[email protected]' , '555-1212'), 
    ('[email protected]', '888-1212') 
    -- etc. 
; 

SELECT * FROM email_phone_notes NATURAL JOIN foo; 
+2

wow đó là tuyệt vời CÚ PHÁP! –

1

Bạn có thể sử dụng một row constructor như thế này :

SELECT * 
FROM email_phone_notes 
WHERE (email, phone) IN (
    ('[email protected]', '555-1212'), 
    ('[email protected]', '888-1212') 
) 

SQLfiddle example

+1

Đáng buồn thay, sẽ không sử dụng chỉ mục. – eggyal

+1

Nguyền rủa bạn, MySQL. Vâng, bản gốc có vẻ không phải: http://sqlfiddle.com/#!2/86c1e/2 – AndreKR

+0

Hãy nhớ rằng một chỉ mục sẽ không được sử dụng trên bảng đó, vì nó quá nhỏ (ít hơn 10 bản ghi). – eggyal

Các vấn đề liên quan