通过 join 语句重现嵌套的 not in 语句
Reproducing a nested not in statement through a join statement
我正在 SQL Server 2014 Express 中通过 AdventureWorks 2012 数据库学习 T-SQL,做一些练习。在其中一个练习中,我被要求为任何未订购的产品显示 productid
和 name
(即 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;
我正在 SQL Server 2014 Express 中通过 AdventureWorks 2012 数据库学习 T-SQL,做一些练习。在其中一个练习中,我被要求为任何未订购的产品显示 productid
和 name
(即 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;