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。

具体步骤:

  1. 将 Orders 表与 Company 表通过 com_id 连接,筛选出 Company.name = 'RED' 的订单,得到向 RED 公司销售过的所有 sales_id。
  2. 从 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 公司销售过的销售人员数量,用于存储子查询结果。