SQL: левое соединение с тремя таблицами - PullRequest
2 голосов
/ 07 февраля 2020

У меня есть три таблицы

Products (idProduct, name)
Invoices(typeinvoice, numberinvoice, date)
Item-invoices(typeinvoice, numberinvoice, idProduct)

Мой запрос должен выбрать все продукты, не проданные в 2019 году. Я могу использовать функцию для получения года по дате, например, год (i. свидание). Я знаю, что товары, которые не отображаются в таблице Товар-счет, являются непроданными. Поэтому я попытался с этими двумя кодами и получить хороший вывод.

   SELECT p.name
   FROM Products p
   EXECPT
   SELECT ii.idProduct
   FROM Item-invoices ii, Invoices i
   WHERE ii.typeinvoice=i.typeinvoice
   AND ii.numberinvoice=i.numberinvocice
   AND year(i.date)=2019

А другой код использует подзапрос:

SELECT p.name
FROM Products p
WHERE p.idProduct NOT IN 
            (SELECT ii.idProduct
            FROM Item-invoices ii, Invoices i
            WHERE ii.typeinvoice=i.typeinvoice
            AND ii.numberinvoice=i.numberinvocice
            AND year(i.date)=2019) 

Ответ заключается в том, как я могу использовать левую команду соединения, чтобы получить тот же вывод. Я пытался с

SELECT p.name
FROM Products p 
LEFT JOIN Item-invoices ii ON
            p.IdProduct=ii.idProduct
LEFT JOIN Invoices i ON
            ii.typeinvoice=i.typeinvoice
            AND ii.numberinvoice=i.numberinvocice
WHERE year(i.date)=2019
AND ii.idProduct IS NULL

Я знаю, что это неправильно, но не могу найти решение

Любая помощь?

1 Ответ

3 голосов
/ 07 февраля 2020

Вы почти у цели. Вам просто нужно переместить условие на дату выставления счета из условия from в предложение on из join.

Условия в предложении WHERE являются обязательными, поэтому то, что вы на самом деле превратили LEFT JOI в INNER JOIN, что никогда не может быть выполнено (поскольку оба условия в предложении WHERE не могут быть истинными в то же время).

SELECT p.name
FROM Products p 
LEFT JOIN Item-invoices ii ON
            p.IdProduct=ii.idProduct
LEFT JOIN Invoices i ON
            ii.typeinvoice=i.typeinvoice
            AND ii.numberinvoice=i.numberinvocice
            AND i.date >= '2019-01-01'
            AND i.date <  '2020-01-01'
WHERE ii.idProduct IS NULL

Обратите внимание, что я изменил ваш фильтр даты на полуоткрытый фильтр, который работает непосредственно с сохраненной датой, без использования функций даты; это более эффективный способ продолжения (поскольку он позволяет базе данных использовать существующий индекс).

...