SQL:用三个表左联接

时间:2020-02-06 22:22:43

标签: sql sqlite join left-join

我有三个桌子

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

我的查询必须选择所有在2019年未售出的产品。我可以使用一个函数从日期中获取年份,例如year(i.date)。我知道商品发票表中未出现的产品是未售出的产品。因此,我尝试使用这两个代码并获得了良好的输出。

   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) 

答案是我如何才能使用left join命令获得相同的输出。我尝试过

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 个答案:

答案 0 :(得分:3)

您快到了。您只需要将发票日期上的条件从from的{​​{1}}子句移动到on的{​​{1}}子句。

join子句中的条件是强制性的,因此您实际上将WHERE变成了LEFT JOI,这是无法实现的(因为{{1}中的两个条件}子句不能同时为true。

INNER JOIN

请注意,我将您的日期过滤器更改为半开过滤器,该过滤器可直接对存储的日期进行操作,而不使用日期函数;这是一种更有效的处理方式(因为它允许数据库使用现有索引)。