leetcode 607. 销售员
题目描述
表: SalesPerson
+-----------------+---------+
| Column Name | Type |
+-----------------+---------+
| sales_id | int |
| name | varchar |
| salary | int |
| commission_rate | int |
| hire_date | date |
+-----------------+---------+
sales_id 是该表的主键。
该表包含销售人员的姓名和 ID 以及他们的工资、佣金率和雇佣日期。
表: Company
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| com_id | int |
| name | varchar |
| city | varchar |
+-------------+---------+
com_id 是该表的主键。
该表包含公司的名称和 ID 以及公司所在的城市。
表: Orders
+-------------+------+
| Column Name | Type |
+-------------+------+
| order_id | int |
| order_date | date |
| com_id | int |
| sales_id | int |
| amount | int |
+-------------+------+
order_id 是该表的主键。
com_id 是 Company 表中 com_id 的外键。
sales_id 是 SalesPerson 表中 sales_id 的外键。
该表包含订单的 ID、日期、公司 ID、销售人员 ID 和金额。
编写一个 SQL 查询,报告没有向公司 RED 销售过任何东西的所有销售人员的姓名。
以任意顺序返回结果表。
查询结果格式如下所示。
示例 1:
输入:
SalesPerson 表:
+----------+------+--------+-----------------+------------+
| sales_id | name | salary | commission_rate | hire_date |
+----------+------+--------+-----------------+------------+
| 1 | John | 100000 | 6 | 4/1/2006 |
| 2 | Amy | 12000 | 5 | 5/1/2010 |
| 3 | Mark | 65000 | 12 | 12/25/2008 |
| 4 | Pam | 25000 | 25 | 1/1/2005 |
| 5 | Alex | 5000 | 10 | 2/3/2007 |
+----------+------+--------+-----------------+------------+
Company 表:
+--------+--------+----------+
| com_id | name | city |
+--------+--------+----------+
| 1 | RED | Boston |
| 2 | ORANGE | New York |
| 3 | YELLOW | Boston |
| 4 | GREEN | Austin |
+--------+--------+----------+
Orders 表:
+----------+------------+--------+----------+--------+
| order_id | order_date | com_id | sales_id | amount |
+----------+------------+--------+----------+--------+
| 1 | 1/1/2014 | 3 | 4 | 10000 |
| 2 | 2/1/2014 | 4 | 5 | 5000 |
| 3 | 3/1/2014 | 1 | 1 | 50000 |
| 4 | 4/1/2014 | 1 | 4 | 25000 |
+----------+------------+--------+----------+--------+
输出:
+------+
| name |
+------+
| Amy |
| Mark |
| Alex |
+------+
解释:
根据订单表,只有 John 和 Pam 向公司 RED 销售过任何东西。
因此,Amy,Mark 和 Alex 没有向公司 RED 销售过任何东西。
解题思路
本题要求找出没有向公司 RED 销售过任何东西的所有销售人员的姓名。
核心思路:先找出所有向 RED 公司销售过的销售人员的 sales_id,然后从 SalesPerson 表中排除这些 sales_id。
具体步骤:
- 将
Orders表与Company表通过com_id连接,筛选出Company.name = 'RED'的订单,得到向 RED 公司销售过的所有sales_id。 - 从
SalesPerson表中查询sales_id不在上述集合中的销售人员姓名。
可以使用 NOT IN 子查询或者 LEFT JOIN ... IS NULL 的方式实现。
解法一:NOT IN 子查询
解题思路
使用子查询找出所有向 RED 公司销售过的 sales_id,然后用 NOT IN 排除这些销售人员。
# Write your MySQL query statement below
SELECT name
FROM SalesPerson
WHERE sales_id NOT IN (SELECT o.sales_idFROM Orders oJOIN Company c ON o.com_id = c.com_idWHERE c.name = 'RED'
);
解法二:LEFT JOIN 排除
解题思路
将 SalesPerson 表与「向 RED 公司销售过的订单」进行 LEFT JOIN,连接不上的行即为没有向 RED 销售过的销售人员。
# Write your MySQL query statement below
SELECT s.name
FROM SalesPerson s
LEFT JOIN (SELECT o.sales_idFROM Orders oJOIN Company c ON o.com_id = c.com_idWHERE c.name = 'RED'
) red ON s.sales_id = red.sales_id
WHERE red.sales_id IS NULL;
复杂度分析
- 时间复杂度:O(N + M),其中 N 为
SalesPerson表行数,M 为Orders表行数。需要对两张表进行扫描和连接。 - 空间复杂度:O(K),K 为向 RED 公司销售过的销售人员数量,用于存储子查询结果。
