![]() |
Модераторы: skyboy |
![]() ![]() ![]() |
|
Reverent |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 65 Регистрация: 30.5.2007 Репутация: нет Всего: нет |
Помогите сделать выборку из каталога с отдельной таблицей свойств.
Добрый день, уважаемые форумчани. Уже несколько дней ломаю голову, как можно реализовать следующую задачу, которая стоит в проекте. Представьте, что у нас есть каталог наподобие такого: id_catalog name А так же у нас есть таблица, которая хранит свойства каждого товара и его значение. id_catalogParam id_catalog label value Как видим мы имеем связь один ко многим. Например у нас есть товар пылесос, а у него может быть очень много параметров. Все вроед выглядет идеально, но проблема наступает на этапе выборки, когда мне нужно создать фильтр. Например я хочу найти все пылесосы, с определенной мощностью и ценой, я пишу.
Но таким образом он находит товары либо с мощностью 300, либо с ценой 7000. А мне нужно полное соответствие, тогда я заменяю OR на AND. Но поиск ничего не дает. И это вполне понятно, нет такой записи где бы value равнялось и тому и другому. Так как решить эту проблему, как провести эту выборку, чтобы она дала товары полного соотевствия. Это сообщение отредактировал(а) Reverent - 1.2.2016, 02:40 |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 2 Всего: 386 |
Есть такая функция - EXISTS
Тонкость в том, что запрос не сможет выдать все свойства товара за раз, только ID товара. Придется потом отдельным запросом их выковыривать. Это сообщение отредактировал(а) ksnk - 1.2.2016, 08:18 -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
igorold |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 557 Регистрация: 22.12.2005 Где: Россия->Урал-& gt;Миасс Репутация: 5 Всего: 17 |
Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Akina |
|
||||||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
Классический подход - это обработка таблицы параметров в подзапросе с получением только тех объектов, для которых найден необходимый комплекс характеристик.
Т.е. подзапрос выглядит приблизительно так:
Все указанные фильтры включаются в секцию WHERE через OR, причём тут допустимы любые типы условий, например:
Количество соответствующих фильтров указывается в секции HAVING, причём там может задаваться и количество, не равное количеству отдельных фильтров - например, если всего указано 5 фильтров, то секция может быть такой:
Полученный подзапрос даёт все id_catalog, которые соответствуют набору фильтров и требуемому количеству соответствий, и это значение используется для отбора записей основной таблицы. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||||
|
|||||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 2 Всего: 386 |
Akina, "Классика" - это бОльшее соответствие стандарту SQL? В смысле EXISTS - это такая mysql фича, которая другими системами может и не поддерживаться.
А вот в mysql реальности есть ли заметные преимущества "классики" перед ESISTS подходом? Интерес шкурный ![]() -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Akina |
|
||||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
Если каталог содержит миллион товаров, из которых набору из десятка фильтров соответствует только десяток записей, EXISTS со своими коррелированными подзапросами отправится курить за угол. Ибо описанный подход изрядно "худеет" самую пухлую из участвующих в этом действе таблиц. Однако если набору фильтров соответствует половина товаров, то EXISTS, несомненно, выиграет. Кроме того, лично я считаю, что для динамического построения запросов EXISTS-шаблон более сложен. Если кто считает иначе - спорить не буду, это очень субъективно. А ещё я считаю, что запрос с EXISTS хуже читаем с точки зрения понимания логики текста запроса. Ну и EXISTS не очень-то предназначен для построения запроса, когда требуется соответствие не строго всем фильтрам, а не менее указанного количества (как в примере "не менее 3 из этих 5").
По-моему, её поддерживают все и вся... -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
tzirechnoy |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
EXISTS есть как миниму в SQL92.
|
|||
|
||||
Zloxa |
|
||||||||||||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 33 Всего: 161 |
Хотел было поспорить, но походу это платформспецифик маси, покуда он не умеет выполнять exists, траснформируя его в semi-join. Увы,
Далее, сорри - ![]() ![]() А так вобще экзистс вполне себе может выполняться и джойном. При высокой селективности и при индексированной паре (тип, значение), отбираем по индексу самый селективный предикат, потом нестедлупим второй.
План
Здесь он сначала по индексу находит property по p.type = 2 and p.value = 2, затем по индексу подтягивает его entity, затем по индексу смотрит для него property по type = 1 и фильтрует по value = 1 Хавингом получается трохан подольше
При низкой селективности, казалось бы, должно быть наоборот. Ведь джойн потребует двух фулсканов там где having потребует одного. Но практика это не подтверждает
Это сообщение отредактировал(а) Zloxa - 2.2.2016, 11:00 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
||||||||||||
|
|||||||||||||
Angel666 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 8.9.2011 Репутация: нет Всего: 1 |
Не знаю как вариант.
1. выбрать id товара по одному свойству допустим цене (получили 30 id) 2. следующий запрос по другому свойству мощности но с ограничением id уже полученных товаров. 3. ну и так далее... Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
Гм... это вариант, навеянный привычкой вытащить все данные на клиента и там их обрабатывать, вместо того, чтобы поручить это SQL-серверу. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | MySQL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |