SELECT Products.name
FROM Products
WHERE NOT EXISTS (
SELECT id
FROM Sections
WHERE name IN ('new','car')
AND NOT EXISTS (
SELECT *
FROM Products_sections
WHERE Products_sections.section_id = Sections.id
AND Products_sections.product_id = Products.id
)
)
Другими словами, выберите те продукты, для которых ни одно из требуемых значений Section.id отсутствует в таблице Products_sections для этого продукта.
Ответ andho's comment:
Можно поставить
NOT EXISTS (<select query>)
в предложение WHERE, как и в любом другом предикате. Он оценивается как ИСТИНА, если в результирующем наборе нет строк, описанных
Пошагово, вот как можно получить ответ на этот запрос:
Шаг 1. Требуется указать все продукты, которые находятся «в разделах« новый »и« автомобиль »».
Шаг 2. Продукт находится в разделах «новый» и «автомобиль», если продукт содержит разделы «новый» и «автомобиль». Эквивалентно, продукт находится в разделах «новый» и «автомобиль», если ни один из этих разделов не содержит продукт. (Обратите внимание на двойной минус: ни не содержит .) Повторно, мы хотим, чтобы все продукты, для которых есть нет обязательный раздел не удалось для содержания продукта.
Обязательные разделы:
SELECT id
FROM Sections
WHERE name IN ('new','car')
Следовательно, желаемыми продуктами являются:
SELECT Products.name
FROM Products
WHERE NOT EXISTS ( -- there does not exist
SELECT id -- a section
FROM Sections
WHERE name IN ('new','car') -- that is required
AND (the section identified by Sections.id fails to contain the product identified by Products.id)
)
Шаг 3. В данном разделе (например, «новый» или «автомобиль») содержит конкретный товар, если в разделе Products_sections есть строка для данного раздела и конкретного товара. Таким образом, данный раздел не может содержать конкретный продукт, если в Products_sections такой строки нет.
Шаг 4. Если запрос ниже содержит содержит строку, раздел section_id содержит содержит product_id product:
SELECT *
FROM Products_sections
WHERE Products_sections.section_id = Sections.id
AND Products_sections.product_id = Products_id
Таким образом, section_id section не может содержать продукта (и это то, что нам нужно выразить), если приведенный выше запрос не создает строку в своем результате, или если NOT EXISTS ().
Кажется сложным, но как только вы получаете это в голову, оно придерживается: все необходимые элементы присутствуют? Да, если не существует обязательного элемента, которого нет.