Выберите объекты, используя несколько критериев, из объекта связи «многие ко многим» - PullRequest
0 голосов
/ 25 апреля 2019

У меня возникают проблемы при выборе объектов типа Product, в которых продукт имеет две или более категорий.

У меня есть следующие таблицы:

product
============
product_id (PK)
name

category
============
category_id (PK)
name

и их ассоциация:

product_category
============
product_id (PFK)
category_id (PFK)

Теперь проблема в том, что я не могу выбрать продукт по нескольким категориям category.category_id с использованием таблицы product_category.

Например: я хочу выбрать все продукты, которые относятся к категории 1, 2, это означает, что в таблице product_category есть два вхождения.

Для выбора всех товаров в одной категории может быть использован следующий выбор

SELECT p.*
FROM product p
JOIN product_category pc using(product_id)
WHERE category_id = 1;

Но как я могу выбрать, где продукт имеет category_id 1 и 2? Запрос должен возвращать только продукты, с которыми связаны обе категории.

WHERE category_id = 1 and category_id = 2;

Это очевидно невозможное совпадение, но как я могу обойти это? Это вообще возможно?

1 Ответ

1 голос
/ 25 апреля 2019

Присоединитесь к производной таблице, в которой вы фильтруете все ассоциации на предмет наличия одной из требуемых категорий.Затем сгруппируйте по продукту и используйте предложение HAVING, которое проверяет, чтобы различное количество категорий было равно количеству требуемых категорий.Продукт, имеющий все требуемые категории, удовлетворит это.

SELECT p.*
       FROM product p
            INNER JOIN (SELECT pc.product_id
                               FROM product_category pc
                               WHERE pc.category_id IN (1, 2)
                               GROUP BY pc.product_id
                               HAVING count(DISTINCT pc.category_id) = 2)
                       ON pc.product_id = p.product_id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...