我通过SQL Server 2014 Express中的AdventureWorks 2012数据库学习T-SQL,做了一些练习。在其中一个练习中,我要求显示productid
和name
以查找尚未订购的任何产品(即productid
未找到sales.salesorderdetail
表)。相当简单,我在下面使用了嵌套的not in
语句,这是正确答案,返回238行。
select p.productid
, p.name
from production.product p
where p.productid not in
(select sod.productid
from sales.salesorderdetail sod
where sod.productid is not null)
order by p.productid;
出于我自己的学习目的,我试图通过使用连接语句来重现这一点。我的尝试在下面,但是它会产生错误的结果,从上述查询中返回所有productid
以及更多,包含504行。
select distinct p.productid
, p.name
from production.product p
inner join sales.salesorderdetail sod on sod.productid <> p.productid
order by p.productid;
为什么不加入sod.productid <> p.productid
会产生与not in
查询相同的结果?因为我自己尝试这个,所以我可以检查工作簿中没有答案。感谢帮助。
答案 0 :(得分:1)
它失败的原因是你将匹配productids不匹配的任何行,这实际上不是你想要的。如果您在选择中添加, p.ProductID, sod.ProductID
,则会更清楚地看到发生的情况。
使用连接执行此操作的“正确”方法是使用left join
并过滤掉具有空值的行:
select p.productid, p.name
from production.product p
left join sales.salesorderdetail sod on sod.productid = p.productid
where sod.ProductID is null
order by p.productid;