【LeetCode Solutions】LeetCode 181 ~ 185 题解
CONTENTS
- LeetCode 181. 超过经理收入的员工(SQL 简单)
- LeetCode 182. 查找重复的电子邮箱(SQL 简单)
- LeetCode 183. 从不订购的客户(SQL 简单)
- LeetCode 184. 部门工资最高的员工(SQL 中等)
- LeetCode 185. 部门工资前三高的所有员工(SQL 困难)
LeetCode 181. 超过经理收入的员工(SQL 简单)
【题目描述】
表:Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
| salary | int |
| managerId | int |
+-------------+---------+
id 是该表的主键(具有唯一值的列)。
该表的每一行都表示雇员的ID、姓名、工资和经理的ID。
编写解决方案,找出收入比经理高的员工。
以任意顺序返回结果表。
结果格式如下所示。
【示例 1】
输入:
Employee 表:
+----+-------+--------+-----------+
| id | name | salary | managerId |
+----+-------+--------+-----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | Null |
| 4 | Max | 90000 | Null |
+----+-------+--------+-----------+输出:
+----------+
| Employee |
+----------+
| Joe |
+----------+解释: Joe 是唯一挣得比经理多的雇员。
【分析】
本题很简单,直接查两个表就行,也可以使用 JOIN
语句连接两个一样的表同时根据条件进行过滤。
【代码】
【方法一】
# Write your MySQL query statement below
SELECT E1.name AS Employee
FROM Employee E1, Employee E2
WHERE E1.managerId = E2.id AND E1.salary > E2.salary;
【方法二】
# Write your MySQL query statement below
SELECT E1.name AS Employee
FROM Employee E1 JOIN Employee E2
ON E1.managerId = E2.id AND E1.salary > E2.salary;
LeetCode 182. 查找重复的电子邮箱(SQL 简单)
【题目描述】
表:Person
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| email | varchar |
+-------------+---------+
id 是该表的主键(具有唯一值的列)。
此表的每一行都包含一封电子邮件。电子邮件不包含大写字母。
编写解决方案来报告所有重复的电子邮件。请注意,可以保证电子邮件字段不为 NULL
。
以任意顺序返回结果表。
结果格式如下例。
【示例 1】
输入:
Person 表:
+----+---------+
| id | email |
+----+---------+
| 1 | a@b.com |
| 2 | c@d.com |
| 3 | a@b.com |
+----+---------+输出:
+---------+
| Email |
+---------+
| a@b.com |
+---------+解释: a@b.com 出现了两次。
【分析】
直接使用 GROUP BY
和 HAVING
条件将 email
字段分组并统计数量即可筛选出数量大于 1 的邮件名。
【代码】
# Write your MySQL query statement below
SELECT email
FROM Person
GROUP BY email
HAVING COUNT(email) > 1;
LeetCode 183. 从不订购的客户(SQL 简单)
【题目描述】
Customers
表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
+-------------+---------+
在 SQL 中,id 是该表的主键。
该表的每一行都表示客户的 ID 和名称。
Orders
表:
+-------------+------+
| Column Name | Type |
+-------------+------+
| id | int |
| customerId | int |
+-------------+------+
在 SQL 中,id 是该表的主键。
customerId 是 Customers 表中 ID 的外键( Pandas 中的连接键)。
该表的每一行都表示订单的 ID 和订购该订单的客户的 ID。
找出所有从不点任何东西的顾客。
以任意顺序返回结果表。
结果格式如下所示。
【示例 1】
输入:
Customers table:
+----+-------+
| id | name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Orders table:
+----+------------+
| id | customerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+输出:
+-----------+
| Customers |
+-----------+
| Henry |
| Max |
+-----------+
【分析】
在 Customers
表上进行左连接,若 Orders
表中没有某个客户的订单,则连接后 Orders
表中对应的 id
与 customerId
均为 NULL
。
还可以判断 Customers
表中客户的 id
是否在 Orders
表中作为 customerId
出现过,如果没出现说明该客户没有任何订单。
【代码】
【方法一】
# Write your MySQL query statement below
SELECT name AS Customers
FROM Customers LEFT JOIN Orders
ON Customers.id = Orders.customerId
WHERE Orders.customerId IS NULL;
【方法二】
# Write your MySQL query statement below
SELECT name AS Customers
FROM Customers
WHERE id NOT IN (SELECT customerId FROM Orders);
LeetCode 184. 部门工资最高的员工(SQL 中等)
【题目描述】
表:Employee
+--------------+---------+
| 列名 | 类型 |
+--------------+---------+
| id | int |
| name | varchar |
| salary | int |
| departmentId | int |
+--------------+---------+
在 SQL 中,id是此表的主键。
departmentId 是 Department 表中 id 的外键(在 Pandas 中称为 join key)。
此表的每一行都表示员工的 id、姓名和工资。它还包含他们所在部门的 id。
表:Department
+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| id | int |
| name | varchar |
+-------------+---------+
在 SQL 中,id 是此表的主键列。
此表的每一行都表示一个部门的 id 及其名称。
查找出每个部门中薪资最高的员工。
按任意顺序返回结果表。
查询结果格式如下例所示。
【示例 1】
输入:
Employee 表:
+----+-------+--------+--------------+
| id | name | salary | departmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
Department 表:
+----+-------+
| id | name |
+----+-------+
| 1 | IT |
| 2 | Sales |
+----+-------+输出:
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
| IT | Max | 90000 |
+------------+----------+--------+解释:Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。
【分析】
可以在 Employee
表中根据 departmentId
进行分组并求出各部门的最高工资,然后查找 Employee
表中 (departmentId, salary)
符合对应部门最高工资的员工。
也可以直接在一个临时的 Employee
表中查找当前员工所在部门的最高工资,这样效率会稍微低一点。
【代码】
【方法一】
# Write your MySQL query statement below
SELECT D1.name AS Department, E1.name AS Employee, salary AS Salary
FROM Employee AS E1 LEFT JOIN Department AS D1
ON departmentId = D1.id
WHERE (departmentId, salary) IN (SELECT departmentId, MAX(salary) FROM Employee GROUP BY departmentId);
【方法二】
# Write your MySQL query statement below
SELECT D1.name AS Department, E1.name AS Employee, salary AS Salary
FROM Employee AS E1 LEFT JOIN Department AS D1
ON departmentId = D1.id
WHERE salary = (SELECT MAX(salary) FROM Employee AS E2 WHERE E2.departmentId = E1.departmentId);
LeetCode 185. 部门工资前三高的所有员工(SQL 困难)
【题目描述】
表:Employee
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| id | int |
| name | varchar |
| salary | int |
| departmentId | int |
+--------------+---------+
id 是该表的主键列(具有唯一值的列)。
departmentId 是 Department 表中 ID 的外键(reference 列)。
该表的每一行都表示员工的ID、姓名和工资。它还包含了他们部门的ID。
表:Department
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
+-------------+---------+
id 是该表的主键列(具有唯一值的列)。
该表的每一行表示部门ID和部门名。
公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的高收入者是指一个员工的工资在该部门的不同工资中排名前三。
编写解决方案,找出每个部门中收入高的员工。
以任意顺序返回结果表。
【提示】
没有姓名、薪资和部门完全相同的员工。
【示例 1】
输入:
Employee 表:
+----+-------+--------+--------------+
| id | name | salary | departmentId |
+----+-------+--------+--------------+
| 1 | Joe | 85000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
| 5 | Janet | 69000 | 1 |
| 6 | Randy | 85000 | 1 |
| 7 | Will | 70000 | 1 |
+----+-------+--------+--------------+
Department 表:
+----+-------+
| id | name |
+----+-------+
| 1 | IT |
| 2 | Sales |
+----+-------+输出:
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Joe | 85000 |
| IT | Randy | 85000 |
| IT | Will | 70000 |
| Sales | Henry | 80000 |
| Sales | Sam | 60000 |
+------------+----------+--------+解释:
在IT部门:
- Max的工资最高
- 兰迪和乔都赚取第二高的独特的薪水
- 威尔的薪水是第三高的
在销售部:
- 亨利的工资最高
- 山姆的薪水第二高
- 没有第三高的工资,因为只有两名员工
【分析】
可以在 Employee
表中根据 departmentId
进行分组并求出各部门的最高工资,然后查找 Employee
表中 (departmentId, salary)
符合对应部门最高工资的员工。
也可以直接在一个临时的 Employee
表中查找当前员工所在部门的最高工资,这样效率会稍微低一点。
【代码】
【方法一】
# Write your MySQL query statement below
SELECT D1.name AS Department, E1.name AS Employee, salary AS Salary
FROM Employee AS E1 LEFT JOIN Department AS D1
ON departmentId = D1.id
WHERE (departmentId, salary) IN (SELECT departmentId, MAX(salary) FROM Employee GROUP BY departmentId);
【方法二】
# Write your MySQL query statement below
SELECT D1.name AS Department, E1.name AS Employee, salary AS Salary
FROM Employee AS E1 LEFT JOIN Department AS D1
ON departmentId = D1.id
WHERE salary = (SELECT MAX(salary) FROM Employee AS E2 WHERE E2.departmentId = E1.departmentId);