@Lordao

Как реализовать поиск элементов по критериям?

Есть три таблицы - Item, Detail и DetailsItem. Между собой они создают связь many-to-many. Каким образом можно реализовать поиск Item по определенным Detail.

Например, есть молоток. Он состоит из нескольких частей, таких как: железо, дерево, медь. Мне нужно найти этот молоток по деталям. Например, я вбиваю параметры такие как дерево и медь по которым точно найдется нужный элемент, но если я добавлю дополнительный параметр такой как силикон, то данный элемент отбрасывается.

Также по этим параметрам могут находиться другие элементы, которые содержат в себе железо, дерево и медь, но если один из параметров не совпадает, то элемент должен не отображаться в итоговой выборке.

SELECT item.idItem, detail.idDetail, detail.title FROM item 
JOIN details_item ON item.idItem = details_item.idItem 
JOIN detail ON detail.idDetail = details_item .idDetail 
WHERE detail.title in ("Железо","Дерево","Медь")


Данный запрос находит элементы в которых есть эти детали, но так же отображаются другие элементы, которые имеют совпадение только 1 из 3.
  • Вопрос задан
  • 95 просмотров
Решения вопроса 2
@Vitsliputsli
Примерно так:
SELECT item.title FROM (
  SELECT 
        item.idItem
    FROM item 
    JOIN details_item ON item.idItem = details_item.idItem 
    JOIN detail ON detail.idDetail = details_item .idDetail
    GROUP BY item.idItem
    HAVING  sum(CASE 
        WHEN detail.title in ("Железо","Дерево","Медь") 
        THEN 1 
        ELSE 0 END) = 3
) t
JOIN item ON item.idItem = t.idItem
Ответ написан
@alexalexes
Можно реализовать, но текст запроса нужно конструировать динамически отдельно для конкретного набора обязательных критериев:
select item.idItem
  from item
 where
count (SELECT details_item.idItem FROM details_item 
JOIN detail ON detail.idDetail = details_item .idDetail 
WHERE detail.title = "Железо"
  and details_item.idItem = item.idItem) > 0
  
  and 
  
  count (SELECT details_item.idItem FROM details_item 
JOIN detail ON detail.idDetail = details_item .idDetail 
WHERE detail.title = "Дерево"
  and details_item.idItem = item.idItem) > 0

  and 
  
count (SELECT details_item.idItem FROM details_item 
JOIN detail ON detail.idDetail = details_item .idDetail 
WHERE detail.title = "Медь"
  and details_item.idItem = item.idItem) > 0
  
  .... и так далее, все обязательные критерии прописываем через подзапрос count()

Вариант 2 с нечувствительностью к соответствию одному из параметров поиска:
select idItem
from (select item.idItem,
       count (SELECT details_item.idItem FROM details_item 
                JOIN detail ON detail.idDetail = details_item .idDetail 
               WHERE detail.title = "Железо"
                 and details_item.idItem = item.idItem) as count_1,
  
       count (SELECT details_item.idItem FROM details_item 
                JOIN detail ON detail.idDetail = details_item .idDetail 
               WHERE detail.title = "Дерево"
                 and details_item.idItem = item.idItem) as count_2,
       
       count (SELECT details_item.idItem FROM details_item 
                JOIN detail ON detail.idDetail = details_item .idDetail 
               WHERE detail.title = "Медь"
                 and details_item.idItem = item.idItem) as count_3
                 
                .... и так далее все обязательные критерии через подзрапрос count(...) as count_n 
  from item)  
  where count_1 > 0 and count_2 > 0 and count_3 > 0 -- строгое соответствие параметрам поиска
     -- тут делаем логику нечувствительности к одному из параметров поиска
     or count_1 = 0 and count_2 > 0 and count_3 > 0
     or count_1 > 0 and count_2 = 0 and count_3 > 0
     or count_1 > 0 and count_2 > 0 and count_3 = 0
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
29 мар. 2024, в 18:19
20000 руб./за проект
29 мар. 2024, в 18:08
2500 руб./за проект
29 мар. 2024, в 17:51
40000 руб./за проект