Не могу составить запрос с группировкой данных - MySQL
Формулировка задачи:
Здравствуйте. Никак не могу сообразить, как составить запрос, делающий выборку из таблицы (см. в конце сообщения) по следующему принципу:
1) Входные данные для запроса - это множество значений fam_id, например, fam_id IN (31,32,34), и пара значений opt_id => opt_val, например, (opt_id=4 and opt_val=9).
Пока все просто...
2) А вот далее - нужно для всех строк, которые выбрали по условию 1 - вывести и строки со всеми остальными значениями opt_id и opt_val, имеющие такое же fam_id, но отличный от заданного opt_id.
Пока решил эту задачу с помощью обработки запроса php и построения с его помощью другого запроса "на лету", но уж как-томного получается и запросов, и лишнего кода.
Чую, что это можно как-то одним SQL-запросом с применением групировки и вложенных запросов сделать, но не могу допереть, как.
Пример таблицы с данными - ниже.
src |
src_id |
fam_id |
opt_id |
opt_val |
opt_code |
opt_pos |
opt | 2050 | 31 | 2 | 2 | 5 | 2 |
opt | 2057 | 31 | 4 | 9 | J | 4 |
opt | 4351 | 31 | 20 | 132 | 0 | 0 |
opt | 2054 | 31 | 4 | 6 | B | 4 |
opt | 2061 | 31 | 4 | 13 | E | 4 |
opt | 2051 | 31 | 2 | 3 | C | 2 |
opt | 2058 | 31 | 4 | 10 | S | 4 |
opt | 2048 | 31 | 1 | 1 | 3 | 1 |
opt | 2055 | 31 | 4 | 7 | D | 4 |
opt | 2052 | 31 | 3 | 4 | 1 | 3 |
opt | 2059 | 31 | 5 | 11 | F | 5 |
opt | 2049 | 31 | 1 | 2 | 5 | 1 |
opt | 2056 | 31 | 4 | 8 | F | 4 |
opt | 2053 | 31 | 3 | 5 | 4 | 3 |
opt | 2060 | 31 | 5 | 12 | 3 | 5 |
sfx | 2 | 32 | 19 | 129 | 2A | -1 |
opt | 4352 | 32 | 20 | 132 | 0 | 0 |
opt | 2062 | 32 | 3 | 5 | 1 | |
opt | 3918 | 32 | 1 | 2 | 0 | 0 |
sfx | 1 | 32 | 19 | 128 | 1A | -1 |
opt | 2063 | 32 | 3 | 14 | M | 1 |
opt | 4335 | 33 | 3 | 213 | 0 | 0 |
opt | 3901 | 33 | 2 | 54 | TD | 1 |
opt | 4410 | 33 | 20 | 132 | 0 | 0 |
opt | 4336 | 33 | 4 | 8 | 0 | 0 |
opt | 3902 | 33 | 2 | 114 | TG | 1 |
opt | 4337 | 33 | 1 | 2 | 0 | 0 |
opt | 2064 | 34 | 3 | 5 | 1 | |
sfx | 3 | 34 | 19 | 128 | 1A | -1 |
opt | 2065 | 34 | 3 | 14 | M | 1 |
Перечитал еще раз свой вопрос, может быть, не понятно объяснил.
В общем, принцип таков - если нашлись строки с fam_id из списка значений, в которых переданные значения opt_id и opt_val равны нужным значениям - то нужно вывести и не только эти строки, но и строки с opt_id, не проверяемые запросом.
Физический смысл этого запроса такой. Эта таблица у меня - это список значений опций различных моделей устройство. (fam_id, это и есть модель). У каждого устройства есть шильд, в позиции которой могут быть отмечены его модификации. (то есть opt_id - это идентификаторы таких опций, как к примеру диапазон рабочих температур, тип корпуса, напряжение питания и т.д., ну и opt_val - это соответствующее значение этой опции из списка значений ).
Соответственно, если происходит поиск устройства по какому-то параметру, например, диапазон температуры - то мне нужно вывести не только строку из базы, описывающую опцию с диапазоном температуры (то есть определенным значением opt_id и opt_val), но и опции, не относящиеся к диапазону температуры, на которые условия не наложены. (То есть скажем если мы ищем модификацию изделия с диапазоном температуры типа "5" - то при этом нужно вывести и все варианты напряжений питания, типов корпусо в и прочие параметры, которые фильтром поиска не отсекаются).
Вот, может быть, так понятнее.
Решение задачи: «Не могу составить запрос с группировкой данных»
textual
Листинг программы
SELECT * FROM options_combos WHERE ((fam_id IN (31,32,33))) AND ( 0 OR ( opt_id=3 AND opt_val IN (5,4) ) OR ( opt_id=4 AND opt_val IN (7,9) ) ) OR (opt_id NOT IN(3,4))
Объяснение кода листинга программы
- В этом коде выполняется запрос к таблице
options_combos
. - В запросе используется условие WHERE.
- Условие состоит из нескольких частей, разделенных логическими операторами OR и AND.
- Первая часть условия:
(fam_id IN (31,32,33))
. Здесь выбираются строки, где значение столбцаfam_id
равно одному из чисел в списке (31,32,33). - Вторая часть условия:
( 0 OR ( opt_id=3 AND opt_val IN (5,4) ) OR ( opt_id=4 AND opt_val IN (7,9) )
. Здесь выбираются строки, где выполняется хотя бы одно из трех условий:- opt_id равно 3 и opt_val равно 5 или 4.
- opt_id равно 4 и opt_val равно 7 или 9.
- opt_id не равно 3 и opt_id не равно 4.
- Третья часть условия:
OR (opt_id NOT IN(3,4))
. Здесь выбираются строки, где opt_id не равно 3 и opt_id не равно 4. - В результате выполнения запроса выбираются все строки, которые удовлетворяют хотя бы одному из условий.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д