为什么 'NOT IN' 有效而 'NOT EXISTS' 无效?

Why did the 'NOT IN' work but not the 'NOT EXISTS'?

我一直在努力改进我的 SQL 并尝试使用 'NOT EXISTS' 函数。我需要找到没有向公司 'RED'.

销售的销售人员的姓名

我试过了,但没用:

SELECT DISTINCT
sp.name

FROM salesperson sp

WHERE NOT EXISTS (

SELECT 
ord.sales_id

FROM
company cmp
LEFT JOIN orders ord
on cmp.com_id=ord.com_id
    
WHERE cmp.name = 'RED')

此查询 运行 但返回了 NULL。然后我把它改成了这个,它工作正常:

SELECT DISTINCT
sp.name

FROM salesperson sp

WHERE sp.sales_id NOT IN (

SELECT 
ord.sales_id as sales_id

FROM
company cmp
left join orders ord
on cmp.com_id=ord.com_id
    
WHERE cmp.name = 'RED')

有人可以解释为什么 'NOT EXISTS' 在这种情况下不起作用吗?
.
.
.
.
.
.
为了以防万一,下面是完整的练习:

给定三个 table:销售人员、公司、订单
输出 table 销售人员中所有没有销售给公司 'RED'.

的姓名

Table: 营业员

sales_id 姓名 工资 commission_rate hire_date
1 约翰 100000 6 2006 年 4 月 1 日
2 艾米 120000 5 2010 年 5 月 1 日
3 马克 65000 12 2008 年 12 月 25 日
4 帕姆 25000 25 2005 年 1 月 1 日
5 亚历克斯 50000 10 2007 年 2 月 3 日

table个营业员持有营业员信息。每个销售人员都有一个sales_id和一个名字。

Table:公司

com_id 姓名 城市
1 红色 波士顿
2 橙色 纽约
3 黄色 波士顿
4 绿色 奥斯汀

table公司持有公司信息。每个公司都有一个 com_id 和一个名称。

Table:订单

order_id order_date com_id sales_id 金额
1 2014 年 1 月 1 日 3 4 100000
2 2014 年 2 月 1 日 4 5 5000
3 2014 年 3 月 1 日 1 1 50000
4 2014 年 4 月 1 日 1 4 25000

table个订单持有销售记录信息,销售员和客户公司用sales_id和com_id表示。

预期输出

姓名
艾米
马克
亚历克斯

解释:

根据table订单中的订单'3'和'4',很容易看出只有销售人员'John'和'Pam'有销售给公司'RED' , 所以我们需要输出 table salesperson.

中的所有其他名称

我认为你的两个查询完全不同。

  1. NOT EXISTS - 当该子查询没有 return 数据时,这将 return 数据。这将始终 return 一些数据,因此您将始终得到空值。您需要使用 WHERE sp.sales_id = ord.sales_id AND cmp.name = 'RED'
  2. 将此子查询与主查询连接起来
  3. NOT IN - 这就是您的目的所需要的。您可以看到它清楚地为您提供了不在(子查询)条件下的数据。

等效的NOT EXISTS需要一个关联子句:

SELECT sp.name
FROM salesperson sp
WHERE NOT EXISTS (SELECT ord.sales_id
                  FROM company cmp JOIN
                       orders ord
                       ON cmp.com_id = ord.com_id
                  WHERE sp.sales_id = ord.sales_id AND
                          cmp.name = 'RED'
                 );

NOT INNOT EXISTS 版本都不需要在子查询中使用 LEFT JOIN。事实上,LEFT JOIN 在某种程度上违背了逻辑的目的。

如果没有相关子句,子查询将运行,如果任何 cmp.name'RED',它将运行 return 行。情况似乎如此,因此 NOT EXISTS 总是 return 错误。