描述
给定 3 个表: salesperson, company, orders。
输出所有表 salesperson 中,没有向公司 'RED' 销售任何东西的销售员。
解释
输入
表: salesperson
+----------+------+--------+-----------------+-----------+
| 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 和他的名字 name 。
表: company
+---------+--------+------------+
| com_id | name | city |
+---------+--------+------------+
| 1 | RED | Boston |
| 2 | ORANGE | New York |
| 3 | YELLOW | Boston |
| 4 | GREEN | Austin |
+---------+--------+------------+
表 company 存储了所有公司的信息。每个公司都有一个公司编号 com_id 和它的名字 name 。
表: orders
+----------+------------+---------+----------+--------+
| 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 。
输出
+------+
| name |
+------+
| Amy |
| Mark |
| Alex |
+------+
解释
根据表 orders 中的订单 '3' 和 '4' ,容易看出只有 'John' 和 'Pam' 两个销售员曾经向公司 'RED' 销售过。
所以我们需要输出表 salesperson 中所有其他人的名字。
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sales-person
审题:三表联合查询
思考:三表联合查询
解题:
解法一
集合差算法。
从全部销售员中排除掉向RED公司卖过的销售员。
先找出向RED公司卖过东西的销售员。
(
select distinct O.sales_id
from Company as C join Orders as O
on(C.name = 'RED' and C.com_id = O.com_id)
) as A
从全部销售员中排除掉这些销售员。
用left join
select SP.name
from salesperson as SP left join
(
select distinct O.sales_id
from Company as C join Orders as O
on(C.name = 'RED' and C.com_id = O.com_id)
) as A
on(SP.sales_id = A.sales_id)
where A.sales_id is NULL
解法二
每个人销售产品给公司。找出每个人业务往来的公司。
select *
FROM
salesperson AS SP LEFT JOIN Orders AS O
ON(SP.sales_id = O.sales_id)
left join Company AS C
ON(C.com_id = O.com_id)
注意:存在某些人没有与任何公司有业务往来。也存在某些公司没有订单。所以用left join保留没有业务的人。
对人分组,统计每个人与red公司相关的订单数。并找出订单数为0的人。
SELECT max(SP.NAME) AS `name`
FROM
salesperson AS SP LEFT JOIN Orders AS O
ON(SP.sales_id = O.sales_id)
left join Company AS C
ON(C.com_id = O.com_id)
GROUP BY SP.sales_id
HAVING SUM(If(C.NAME='RED',1,0)) = 0
知识点:
HAVING 子句
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
HAVING 子句可以让我们筛选分组后的各组数据。