MySQL: как массивы SELECT строк с несколькими парами в предложении WHERE

Скажем, у меня есть таблица email_phone_notes, которая выглядит так:

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

Таким образом, каждая комбинация электронной почты и телефона уникальна, но у вас может быть несколько адресов электронной почты с разными номерами телефонов и наоборот. Это немного надуманно, но это отражает мой сценарий.

Я хотел бы сделать такой запрос:

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

Но я бы хотел сделать несколько пар одновременно, поэтому мне не нужно делать несколько запросов SELECT. Также важно сохранить пары вместе, потому что я не хочу возвращать ошибочную комбинацию телефона/электронной почты, которая не запрашивалась.

Я мог бы сделать что-то подобное, но для возможности нескольких сотен значений запрос будет очень длинным.

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

Есть ли более элегантное решение, или я должен придерживаться этого? Спасибо!

Ответ 1

Если вы после элегантного SQL, вы можете использовать конструкторы строк:

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

Тем не менее, это вовсе не удобно для индексирования и не рекомендуется для таблицы любого значительного размера. Вместо этого вы можете материализовать таблицу с вашими желаемыми парами и присоединиться к ней со своей таблицей:

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;

Или еще предварительно заполнить (временную) таблицу:

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;