【LeetCode Solutions】LeetCode 181 ~ 185 题解

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 BYHAVING 条件将 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 表中对应的 idcustomerId 均为 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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柃歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值