@alst161

Как организовать сложный запрос в SQL?

Выбился из сил. Как реализовать следующее:
есть таблица "product_attribute" следующей структуры (с мини примером):
product_id attribute_id text
105 5 100
105 8 55
105 9 92
106 5 100
106 8 95
106 9 93
107 5 100
107 8 55
107 9 80

и таблица с категориями "product_category"
product_id category_id
105 8
106 8
107 8

Нам надо получить фильтр, где пользователь указывает категорию и несколько атрибутов (например: категория - 8, выбранные атрибуты attribute_id 5 с text 100 и attribute_id 8 с text 55. надо выбрать оставшиеся варианты атрибутов в данном случае должно вернуть attribute_id=9, text=92 и attribute_id=9, text=80
ещё поясню: это фильтр шин на сайте, где используются такие атрибуты как радиус, ширина, высота, сезонность. фильтр работает ajax. каждый раз при выборе одного из селекторов, он обновляет не выбранные подгружая только допустимые значения
какие есть мысли?
  • Вопрос задан
  • 215 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Как-то так:
SELECT DISTINCT `a`.`attribute_id`, `a`.`text`
  FROM (
    SELECT DISTINCT `p`.`id`
      FROM `product` AS `p`
      JOIN `product_category` AS `c` ON `c`.`product_id` = `p`.`id` 
        AND `c`.`category_id` = :categoryId
      JOIN `product_attribute` AS `a1` ON `a1`.`product_id` = `p`.`id`
        AND `a1`.`attribute_id` = :attribute1 AND `a1`.`text` = :attrValue1
      JOIN `product_attribute` AS `a2` ON `a2`.`product_id` = `p`.`id`
        AND `a2`.`attribute_id` = :attribute2 AND `a2`.`text` = :attrValue2
      ...
      JOIN `product_attribute` AS `aN` ON `aN`.`product_id` = `p`.`id`
        AND `aN`.`attribute_id` = :attributeN AND `aN`.`text` = :attrValueN
  ) AS `pr`
  JOIN `product_attribute` AS `a` ON `a`.`product_id` = `p`.`id`
  WHERE `a`.`attribute_id` NOT IN (:attribute1, :attribute2,... attributeN)
  ORDER BY `a`.`attribute_id, `a`.`text`
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Joysi75
select distinct pa.attribute_id , pa.text from product_attribute pa, product_category pb
where p.product_id = pa.product_id and p.category_id=8 and
pa.product_id  not in (
  select pa2.product_id from product_attribute pa2
     where (pa2.attribute_id=9 and pa2.text=92) or (pa2.attribute_id=8 and pa2.text=55)
) and
not((pa.attribute_id=9 and pa.text=92) or (pa.attribute_id=8 and  pa.text=55))

Выражения по типу (pa.attribute_id=9 and pa.text=92) or (pa.attribute_id=8 and pa.text=55) надо формировать динамически или

Создать третью таблицу filtr_sess (sid, attribute_id, text) куда перед вызовом закидывать текущую сессию + выбранные атрибуты. Тогда вызов можно осуществлять только по Sid-у и Category_Id.
Примерно так (пишу без доступа к СУБД с чужого ПК, прошу не винить в синтаксисе):
select distinct pa.attribute_id , pa.text from product_attribute pa, product_category pb, filtr_sess fs
where p.product_id = pa.product_id and p.category_id=8 and
pa.product_id  not in (
select pa2.product_id from product_attribute pa2, filtr_sess s
     where (pa2.attribute_id=s.id and pa2.text=s.text and s.sid=X)
) and fs.sid=X and pa.attribute_id <> fs.id and pa.text <> fs.text
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы