为什么 '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.
中的所有其他名称
我认为你的两个查询完全不同。
NOT EXISTS
- 当该子查询没有 return 数据时,这将 return 数据。这将始终 return 一些数据,因此您将始终得到空值。您需要使用 WHERE sp.sales_id = ord.sales_id AND cmp.name = 'RED'
将此子查询与主查询连接起来
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 IN
和 NOT EXISTS
版本都不需要在子查询中使用 LEFT JOIN
。事实上,LEFT JOIN
在某种程度上违背了逻辑的目的。
如果没有相关子句,子查询将运行,如果任何 cmp.name
是 'RED'
,它将运行 return 行。情况似乎如此,因此 NOT EXISTS
总是 return 错误。
我一直在努力改进我的 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.
中的所有其他名称我认为你的两个查询完全不同。
NOT EXISTS
- 当该子查询没有 return 数据时,这将 return 数据。这将始终 return 一些数据,因此您将始终得到空值。您需要使用WHERE sp.sales_id = ord.sales_id AND cmp.name = 'RED'
将此子查询与主查询连接起来
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 IN
和 NOT EXISTS
版本都不需要在子查询中使用 LEFT JOIN
。事实上,LEFT JOIN
在某种程度上违背了逻辑的目的。
如果没有相关子句,子查询将运行,如果任何 cmp.name
是 'RED'
,它将运行 return 行。情况似乎如此,因此 NOT EXISTS
总是 return 错误。