Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите составить запрос 
V
    Опции темы
maxipub
Дата 18.11.2014, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Задача вроде примитивная, но уперся и не могу сдвинуться с мертвой точки. Бывает.

Есть группы параметров (чекбоксы):

Код
группа №1
параметр id 1 [x]
параметр id 2 [x]
параметр id 3 [ ]

группа №2
параметр id 4 [ ]
параметр id 5 [x]
параметр id 6 [ ]

группа №3
параметр id 7 [ ]
параметр id 8 [ ]
параметр id 9 [ ]


id всех параметров уникальны, и они сгруппированы по группам smile (как именно происходит группировка - не важно, у меня загвоздка с подходом к формированию самого SQL запроса)

Пользователь выбирает любые параметры по своему усмотрению. Нам надо выбрать из БД записи, для которых в группе указан хотя бы один параметр.

Например, пользователь выбрал id 1 и 2 из группы №1 и id 5 из группы №2 (как изображено выше). Значит нам надо выбрать записи из базы, у которых есть (type_id=1 ИЛИ type_id=2) И type_id=5.

В БД вся структура хранится просто списком:

Код
type_id        data_id
1            1
2            1
3            1
9            1
2            2
5            2


Т.е. с учетом данных, выбирается только data_id = 2.

Я сперва сдуру так и сделал, в лоб:

Код
SELECT data_id FROM types WHERE (type_id=1 OR type_id=2) AND (type_id=5)


Потом сразу понял как я ступил smile кто сможет помочь с запросом? Возможно, поменять структуру таблицы со списком? Но тут следует учитывать, что мы не знаем ни точное количество групп, ни количество параметров в них, так что велосипед типа запихнуть девять type_id в одну запись не прокатит. smile 

Я уже подумал было сделать вспомогательную таблицу, которая будет хранить список всех возможных комбинаций текущих параметров групп с индексами каждой конкретной комбинации, а в types будет просто по одной строке - combination_id и data_id. Но это реальный гемор, плюс все это постоянно надо будет обновлять при любом изменении параметров или групп... smile 
PM MAIL   Вверх
Akina
Дата 18.11.2014, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Используй следующий шаблон.
Код

SELECT data_id 
FROM types 
GROUP BY data_id 
HAVING SUM(type_id IN (список значений группы))
AND SUM(type_id IN (список значений другой группы))
AND ...

То есть применительно к твоему примеру это будет 
Код

SELECT data_id 
FROM types 
GROUP BY data_id 
HAVING SUM(type_id IN (1, 2))
AND SUM(type_id IN (5))

Это - случай "хотя бы одна из".
Если требуется, чтобы для группы было от M до N галочек - для неё соответственно будет условие 
Код

AND SUM(type_id IN (список значений группы)) between M and N

Не менее M (исходный случай - "хотя бы одна из", - формально эквивалентен "не менее 1", но тут особый случай, с 1 можно и не сравнивать)
Код

AND SUM(type_id IN (список значений группы)) >= M

Не более M
Код

AND SUM(type_id IN (список значений группы)) <= M

Ни одной
Код

AND SUM(type_id IN (список значений группы)) = 0


Добавлено @ 15:18
PS. В примере вроде бы хочется заменить 
Код

AND SUM(type_id IN (5))

на 
Код

AND SUM(type_id = 5)

Не советую - единообразие шаблона дороже, чем дополнительная обработка "особых" случаев. А серверу так и вовсе пофиг.

Это сообщение отредактировал(а) Akina - 18.11.2014, 15:20


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxipub
Дата 18.11.2014, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Блин, HAVING SUM это что-то гениальное, первый раз такое вижу! smile  smile  smile 
PM MAIL   Вверх
Akina
Дата 18.11.2014, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Код

HAVING SUM(выражение)

полностью эквивалентен
Код

HAVING SUM(выражение) != 0

Ибо любое ненулевое значение интерпретируется как True, нулевое как False, а NULL групповой SUM() не даёт в принципе.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxipub
Дата 18.11.2014, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 517
Регистрация: 22.10.2009

Репутация: 1
Всего: 1



Цитата(Akina @  18.11.2014,  15:27 Найти цитируемый пост)
полностью эквивалентен

Принцип действия тут ясен. Порадовал сам подход, конструкция. smile

Добавлено через 2 минуты и 33 секунды
Цитата(Akina @  18.11.2014,  15:13 Найти цитируемый пост)
PS. В примере вроде бы хочется заменить

Цитата(Akina @  18.11.2014,  15:13 Найти цитируемый пост)
Не советую

Да эт ясно. Там запрос составляется в php while-цикле, все подходящее скидывается в массив, implode в implode и вуаля! smile  smile 
PM MAIL   Вверх
Akina
Дата 18.11.2014, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Ну просто минус одна проверка. На скорость оно, конечно, не повлияет... это как буквы экономить, вставляя тире в середину слова.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0520 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.