MySQL: How to bulk SELECT rows with multiple pairs in WHERE clause

流过昼夜 提交于 2019-11-27 23:48:49

问题


Let's say I have a table, email_phone_notes that looks like this:

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

So, each email/phone combination is unique, but you could have several email addresses with different phone numbers and vice versa. This is a little contrived but it mirrors my scenario.

I'd like to do a query like this:

SELECT * FROM email_phone_notes  WHERE email = 'foo@bar.com' AND phone = '555-1212';

But, I'd like to do multiple pairs at once so I don't have to make several SELECT queries. It's also important to keep the pairs together because I don't want to return an errant phone/email combination that wasn't requested.

I could do something like this, but for the possibility of several hundred values the query will be really long.

SELECT * FROM email_phone_notes WHERE ( 
  (email='foo@bar.com' && phone='555-1212') || 
  (email='test@test.com' && phone='888-1212') || 
   ...

Is there a more elegant solution, or should I stick with this? Thanks!


回答1:


If you're after elegant SQL, you could use row constructors:

SELECT * FROM email_phone_notes WHERE (email, phone) IN (
  ('foo@bar.com'  , '555-1212'),
  ('test@test.com', '888-1212')
  -- etc.
);

However, that's not at all index-friendly and would not be recommended on a table of any significant size. Instead, you could materialise a table with your desired pairs and join that with your table:

SELECT * FROM email_phone_notes NATURAL JOIN (
  SELECT 'foo@bar.com' AS email, '555-1212' AS phone
UNION ALL
  SELECT 'test@test.com', '888-1212'
-- etc.
) t;

Or else pre-populate a (temporary) table:

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
  ('foo@bar.com'  , '555-1212'),
  ('test@test.com', '888-1212')
  -- etc.
;

SELECT * FROM email_phone_notes NATURAL JOIN foo;



回答2:


You can use a row constructor like this:

SELECT *
FROM email_phone_notes
WHERE (email, phone) IN (
  ('foo@bar.com', '555-1212'),
  ('test@test.com', '888-1212')
)

SQLfiddle example



来源:https://stackoverflow.com/questions/13426203/mysql-how-to-bulk-select-rows-with-multiple-pairs-in-where-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!