Можно ли использовать WHERE IN в запросах MySQL с набором полей?
Нужно выбрать все записи из таблицы по значению 2-х полей, входящих в определенный набор значений.
Можно ли использовать WHERE IN подобным образом:
SELECT *
FROM table
WHERE (id, name) IN ((value11, value12), (value21, value22), (value31, value32))
Ни в каких доках на подобное описание данного условного оператора не наткнулся. MySQL запросы выполнят, но вот Doctrine ругается на такое использование, что вызвало кучу сомнений по поводу валидности таких запросов.
Подскажите, являются ли правильными такие запросы? Может кто сталкивался с описанием подобного использования?
Результатом выборки будет где-то 10к строк. Дёргать в цикле базу совсем не вариант, отвалится по времени. Как вариант можно слепить все условия запроса через OR, но мне казалось, что должно существовать более элегантное решение.
Без разницы сколько строк. Готовьте данные заранее, подставляйте в SQL перед самым выполнением.
Ваши условия нельзя заменить where id >= значение1 and id < значение2, например?
Выборка идёт по паспортным данным, а именно серия паспорта + номер, так что заменить условие, увы, нет возможности. Данные заранее подготовлены, поэтому и был большой соблазн просто передать ORM в качестве параметра массив данных и получить ответ.
wwspb: Т.е. у вас есть набор пар серия+номер паспорта (id) и, скажем ФИО (name), вам нужно всю информацию из таблицы только по ним получить?
Если id - это первичный ключ, вам name вообще не нужно использовать для выборки.
Даже если данные вам приходят уже подготовленными, обрабатывайте их повторно и засовывайте в запрос
select * from table
where id in (value1, value2, value3...valueN).
Draconian: К сожалению, паспортные данные не являются первичным ключом. Есть пары значений номер + серия. В таблице они хранятся в разных полях, причём значения эти не уникальные. Нужно выбрать все записи, где совпадают и номер, и серия.
Вот и получается, что пока кроме решения "в лоб" (слепить все пары через OR) других вариантов не нашёл.
Draconian: Почему? У людей могут совпадать номера паспортов, но при этом будут разные серии. Это же применимо и в обратном порядке: совпадают серии, но при этом разные номера.
wwspb: Потому что пара серия+номер уникальная для каждого человека. Если у вас там автоинкремент на таблице, в которой хранится информация о паспортах людей, то это избыточно.
wwspb: Отчего же, нормализация - это избавление от избыточности. Составные ключи - вполне обычная часть архитектуры БД. Вот здесь практически ваш пример с паспортом приведен здесь. Только там номер паспорта изначально представлен объединенным.
Можно еще попробовать сделать так, но я не уверен, что это будет работать:
select * from table
where concat(id, name) in (value1, value2...)