Комбинации «многие ко многим»

У меня есть следующее стандартное отношение «многие ко многим»: http://sqlfiddle.com/#!9/43bd68/28/0

(упрощенная версия) – у меня есть продукт 1 с категориями 1, 2 и 3 и продукт 2 с категориями 1 и 3.

Чего я пытаюсь добиться, так это выбрать продукты, принадлежащие к определенной комбинации категорий.

Чтобы проиллюстрировать это:

  • Получите продукты, которые относятся к категориям (1 или 2) и относятся к категориям (3). Это должно вернуть оба продукта 1 и 2
  • Получите продукты, которые относятся к категориям (2) и относятся к категориям (3). Это должно возвращать только продукт 1

Категории должны вести себя как «фильтры» — поэтому моей первоначальной мыслью было установить WHERE category IN (1, 2) AND category IN (3), но это не работает, так как категория представляет собой одно значение для одной строки. Я думаю, мне нужно что-то вроде «для каждого продукта, а затем внутри продукта проверьте, есть ли у него категория (1 или 2) и категория (3)».

Можно ли добиться этого с помощью SQL-запроса?


person o15a3d4l11s2    schedule 12.08.2016    source источник


Ответы (1)


Вы можете использовать такой запрос:

SELECT
  p.name as prodName, p.id as pid
FROM
  Product p
JOIN Category_Product cp ON p.id = cp.product_id
JOIN Category c ON c.id = cp.category_id
WHERE category_id IN (2,3)
GROUP BY pid
HAVING COUNT(*) = 2

Демо здесь

Чтобы реализовать запрос для первого случая, вы должны использовать условный агрегат в предложении HAVING:

SELECT
  p.name as prodName, p.id as pid
FROM
  Product p
JOIN Category_Product cp ON p.id = cp.product_id
JOIN Category c ON c.id = cp.category_id
WHERE category_id IN (1,2,3)
GROUP BY pid
HAVING COUNT(CASE WHEN category_id IN (1,2) THEN 1 END) > 0 AND
       COUNT(CASE WHEN category_id = 3 THEN 1 END) >= 1

Демо здесь

person Giorgos Betsos    schedule 12.08.2016
comment
Большое спасибо за быстрый ответ. Не могли бы вы привести пример относительно первого случая - category IN (1,2) AND category IN (3)? - person o15a3d4l11s2; 12.08.2016