Получение только строк, соответствующих всем записям в объединенной таблице (SQL)

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

  • Интернет-провайдер
  • Товар
  • Связь
  • Добавить
  • AddOn / Product (сводная таблица для отношения "многие ко многим").

Каждый Продукт связан с поставщиком Интернет-услуг, каждое подключение указано в списке Продуктов. Каждый продукт может иметь несколько надстроек за счет использования сводной таблицы (в которой просто есть 2 поля: одно для идентификатора продукта и одно для идентификатора надстройки).

Результат, который меня интересует, - это каждое соединение с перечисленными надстройками (для этого я использую MySQL GROUP_CONCAT, чтобы составить список поля имя надстройки, разделенный запятыми). Это нормально работает, запрос выглядит примерно так:

SELECT i.name AS ispname, i.img_link, c.download, c.upload, c.monthly_price, c.link, 
GROUP_CONCAT(a.name) AS addons, SUM(pa.monthly_fee) AS addon_price
FROM isp i JOIN product p ON i.id = p.isp_id
JOIN `connection` c ON p.id = c.product_id LEFT JOIN product_addon pa ON pa.product_id = p.id AND pa.forced = 0
LEFT JOIN addon a ON pa.addon_id = a.id GROUP BY c.id

Я использую ЛЕВЫЕ СОЕДИНЕНИЯ, так как продукты могут вообще не иметь надстроек.

Моя проблема в том, что можно выбрать некоторые надстройки, которые ДОЛЖНЫ иметь перечисленные соединения, представленные в виде списка идентификаторов надстроек, например (1,14 237). Если я добавлю его в качестве дополнительного условия в операторы JOIN (И pa.addon_id В (...)), он вернет все соединения, которые имеют только одно из перечисленных дополнений, но не обязательно все из них.

Есть ли способ вернуть все соединения, которые, как минимум, имеют все надстройки (они также могут иметь дополнительные) через SQL?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
0
2 539
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете добавить к предложению WHERE:

AND NOT EXISTS (SELECT NULL FROM addon a2
                WHERE  a2.addon_id IN (1,14,237)
                AND NOT EXISTS
                ( SELECT NULL
                  FROM   product_addon pa2
                  WHERE  pa2.addon_id = a2.addon_id
                  AND    pa2.product_id = p.product_id
                )
               )

Или эквивалентно:

AND NOT EXISTS (SELECT NULL FROM addon a2
                LEFT JOIN product_addon pa2
                  ON pa2.addon_id = a2.addon_id
                 AND pa2.product_id = p.product_id
                WHERE a2.addon_id IN (1,14,237)
                AND   pa2.product_id IS NULL
                )
               )
Ответ принят как подходящий
GROUP BY set-of-column
HAVING SUM(CASE WHEN ISNULL(pa.addon_id, 0) IN (1,14,237) THEN 1 ELSE 0 END) = 3

Другие вопросы по теме