【问题标题】:Why did the 'NOT IN' work but not the 'NOT EXISTS'?为什么'NOT IN'有效,但'NOT EXISTS'无效?
【发布时间】:2021-10-12 13:02:26
【问题描述】:

我一直在尝试改进我的 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')

有人可以解释为什么“不存在”在这种情况下不起作用吗?
.
.
.
.
.
.
以防万一,这里是完整的练习:

给定三个表:销售人员、公司、订单
输出表 salesperson 中没有对公司 'RED' 进行销售的所有名称。

表格:销售人员

sales_id name salary commission_rate hire_date
1 John 100000 6 4/1/2006
2 Amy 120000 5 5/1/2010
3 Mark 65000 12 12/25/2008
4 Pam 25000 25 1/1/2005
5 Alex 50000 10 2/3/2007

表salesperson 保存销售人员信息。每个销售人员都有一个 sales_id 和一个姓名。

表格:公司

com_id name city
1 RED Boston
2 ORANGE New York
3 YELLOW Boston
4 GREEN Austin

表 company 保存公司信息。每个公司都有一个 com_id 和一个名称。

表格:订单

order_id order_date com_id sales_id amount
1 1/1/2014 3 4 100000
2 2/1/2014 4 5 5000
3 3/1/2014 1 1 50000
4 4/1/2014 1 4 25000

orders表保存销售记录信息,sales_id和com_id分别代表salesperson和customer company。

预期输出

name
Amy
Mark
Alex

解释:

根据表中的订单“3”和“4”,很容易看出只有销售员“John”和“Pam”对公司“RED”有销售,所以我们需要输出所有其他名称餐桌销售员。

【问题讨论】:

  • NOT EXISTS 子查询需要是correlated,即包含销售人员条件。

标签: sql oracle oracle11g exists notin


【解决方案1】:

等效的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 IN 和 NOT EXISTS 版本都不需要在子查询中使用 LEFT JOIN。事实上,LEFT JOIN 在某种程度上违背了逻辑的目的。

如果没有相关子句,子查询会运行,如果cmp.name 是'RED',它将返回行。情况似乎如此,因此 NOT EXISTS 总是返回 false。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-10-13
      • 1970-01-01
      • 2014-12-29
      • 2019-02-02
      • 1970-01-01
      • 2016-02-11
      • 2014-09-03
      • 1970-01-01
      • 2013-12-30
      相关资源
      最近更新 更多