通过 join 语句重现嵌套的 not in 语句

Reproducing a nested not in statement through a join statement

我正在 SQL Server 2014 Express 中通过 AdventureWorks 2012 数据库学习 T-SQL,做一些练习。在其中一个练习中,我被要求为任何未订购的产品显示 productidname(即 productid 未在 sales.salesorderdetail 中找到table)。相当简单,我在下面使用了嵌套的 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 查询相同的结果?因为我是自己尝试的,所以我可以对照的工作簿中没有答案。感谢帮助。

它失败的原因是您将匹配 productid 不匹配的任何行,这实际上不是您想要的。如果将 , p.ProductID, sod.ProductID 添加到 select,您会更清楚地看到发生了什么。

"correct" 使用联接执行此操作的方法是使用 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;