Leetcode Database 刷题
文章目录
- 组合两个表
- 第二高的薪水
- 第N高的薪水
- 分数排名
- 连续出现的数字
- 超过经理收入的员工
- 查找重复的电子邮箱
- 从不订购的客户
- 部门工资最高的员工
- 部门工资前三高的所有员工
- 删除重复的电子邮箱(自连接、删除语句)
- 上升的温度
- 行程和用户
- 大的国家
- 超过5名学生的课
- 育馆的人流量
- 有趣的电影
- 换座位
- 交换工资
175. 组合两个表
左连接
SELECT
p.FirstName,
p.LastName,
a.City,
a.State
FROM
Person p LEFT JOIN Address a
ON
p.PersonId = a.PersonId
176. 第二高的薪水
子查询
ifnull()
函数
SELECT
ifnull(
(
SELECT DISTINCT
Salary
FROM
Employee
ORDER BY
Salary
DESC
LIMIT 1, 1
),
NULL
)
AS SecondHighestSalary
SELECT
(
SELECT DISTINCT
Salary
FROM
Employee
ORDER BY
Salary
DESC
LIMIT 1, 1
)
AS SecondHighestSalary
177. 第N高的薪水
178. 分数排名
180. 连续出现的数字
自连接
如果一个数字连续出现超过 3 次,会返回重复元素,需要使用 DISTINCT
去重。
SELECT DISTINCT
l1.Num AS ConsecutiveNums
FROM
`Logs` l1,
`Logs` l2,
`Logs` l3
WHERE
l1.Num = l2.Num AND l2.Num = l3.Num AND l1.Id = l2.Id - 1 AND l2.Id = l3.Id - 1
181. 超过经理收入的员工
SELECT
e1.NAME AS Employee
FROM
Employee e1,
Employee e2
WHERE
e1.ManagerId = e2.Id
AND e1.Salary > e2.Salary
182. 查找重复的电子邮箱
分组聚合
SELECT
FROM
Person
GROUP BY
HAVING
count(Email) > 1
183. 从不订购的客户
左连接
SELECT
NAME AS Customers
FROM
Customers c LEFT JOIN Orders o ON c.Id = o.CustomerId
WHERE
o.Id IS NULL
范围查询
SELECT
Name AS Customers
FROM
Customers
WHERE
Customers.Id NOT IN (SELECT CustomerId FROM Orders)
184. 部门工资最高的员工
内连接 + 范围查询
SELECT
d.NAME AS Department,
e.NAME AS Employee,
e.Salary
FROM
Employee e,
Department d
WHERE
e.DepartmentId = d.Id
AND (e.DepartmentId, Salary) IN (
SELECT
DepartmentId,
MAX(Salary)
FROM
Employee
GROUP BY
DepartmentId
)
内连接 + 子查询
SELECT
d.NAME AS Department,
e.NAME AS Employee,
e.Salary
FROM
Employee e,
Department d,
(
SELECT
DepartmentId,
MAX(Salary) AS salary
FROM
Employee
GROUP BY
DepartmentId
) AS t
WHERE
e.DepartmentId = d.Id
AND e.DepartmentId = t.DepartmentId
AND e.Salary = t.Salary
185. 部门工资前三高的所有员工
重复薪水的处理
员工的薪水可能相同,前三高工资的记录数可能大于 3,使用
ORDER BY Salary DESC LIMIT 3
无法满足题目要求。并且,本题中相同工资视为同一排名,不会挤占后面的排位。例如 [200, 150, 150, 100, 90],前三高为 [200, 150, 150, 100],而不是 [200, 150, 150]。因此,使用
COUNT(DISTINCT e2.Salary)
去除重复工资的计数。子查询
将子查询结果作为筛选条件,产生类似遍历的效果。在本题中,对于员工表中的每一条记录,通过子查询查找出同一部门中工资高于该记录的员工数,从而判断该记录是否符合前三高条件,完成条件筛选。
分组聚合
一般地,聚合函数与
GROUP BY
、HAVING
配合使用。聚合函数作为筛选条件时,只能出现在HAVING
语句中。聚合函数作为查询结果时,可以单独出现在SELECT
语句中,此时默认分组是整个表。本题中,筛选条件是员工数量,而又不便于划分分组,不得不采用子查询的写法。
连接的条件筛选
ON
用于在生成临时表时的条件筛选;WHERE
用于对已生成的临时表进行条件筛选。以左连接为例,不论
ON
中的条件是否为真,都会返回左表中的记录,即ON
条件对左表无效。而WHERE
作用于临时表,对来自各表中的字段一视同仁。对于内连接,
ON
要求各表都满足筛选条件,原理上与WHERE
作用对象不同,效果上却是完全相同。因此,内连接中ON
可以替代WHERE
,反之不行。实践中,一般使用ON …… AND ……
而很少用到ON …… WHERE ……
。SELECT
d.NAME AS Department,
e1.NAME AS Employee,
e1.Salary
FROM
Employee e1 JOIN Department d
ON
e1.DepartmentId = d.Id
AND
3 > (
SELECT
COUNT(DISTINCT e2.Salary)
FROM
Employee e2
WHERE
e2.Salary > e1.Salary AND e1.DepartmentId = e2.DepartmentId
)
196. 删除重复的电子邮箱(自连接、删除语句)
自连接
多表连接删除:将需要执行操作的表名写在 DELETE 后面。这样,删除只影响部分表,但同时利用多张表进行查询。
DELETE
p1
FROM
Person p1,
Person p2
WHERE
p1.Email = p2.Email AND p1.Id > p2.Id
197. 上升的温度
DATEDIFF()
用于计算两个日期值相差的天数,数据类型可以是 DATE、DATETIME 和 TIMESTAMP,对于 DATETIME 或 TIMESTAMP,该函数仅将日期部分用于计算,并忽略时间部分。
ADDDATE(date, INTERVAL 1 DAY)
对当前日期增加一定量的时间。
SELECT
w2.Id
FROM
Weather w1,
Weather w2
WHERE
ADDDATE(w1.RecordDate, INTERVAL 1 DAY) = w2.RecordDate AND w1.Temperature < w2.Temperature
SELECT
w1.Id AS Id
FROM
Weather w1,
Weather w2
WHERE
DATEDIFF(w1.RecordDate, w2.RecordDate) = 1 AND w1.Temperature > w2.Temperature
262. 行程和用户
595. 大的国家
596. 超过5名学生的课
分组聚合
陷阱:表中存在重复记录,在分组计数时应该去重。例如,
student | class |
---|---|
A | Math |
B | English |
C | Math |
D | Biology |
E | Math |
F | Math |
A | Math |
SELECT
class
FROM
courses
GROUP BY
class
HAVING
count(DISTINCT student) >= 5
601. 育馆的人流量
620. 有趣的电影
MySQL 常用运算符及函数汇总:https://www.jb51.net/article/124096.htm
SELECT
*
FROM
cinema
WHERE
description <> 'boring' AND id % 2 = 1
ORDER BY
rating
DESC
626. 换座位
条件语句 IF(condition, true_operation, false_operationg)
和 CASE……WHEN……THEN……ELSE……THEN……END
聚合函数作为筛选条件时,只能出现在 HAVING
语句中。没有使用 GROUP BY
创建分组,不能直接使用 id=MAX(id)
筛选最大 ID,否则报 Invalid use of group function
错误,只能先通过子查询计算最大值,再进行条件筛选。
SELECT
CASE
WHEN id % 2 = 0
THEN id - 1
WHEN id = (SELECT MAX(id) FROM seat)
THEN id
ELSE id + 1
END AS id, student
FROM
seat
ORDER BY
id
SELECT
IF (
id % 2 = 0,
id - 1,
IF (
id = (SELECT MAX(id) FROM seat),
id,
id + 1
)
) AS id, student
FROM
seat
ORDER BY
id
627. 交换工资
条件语句
UPDATE
salary
SET
sex =
CASE sex
WHEN 'm'
THEN 'f'
ELSE 'm'
END
UPDATE
salary
SET
sex =
IF (sex = 'f', 'm', 'f')
异或/加减交换
UPDATE
salary
SET
sex = CHAR (ASCII(sex) ^ ASCII('m') ^ ASCII('f'))
UPDATE
salary
SET
sex = CHAR (ASCII('m') + ASCII('f') - ASCII(sex))
题目列表:
- Leetcode 175. 组合两个表
- Leetcode 176. 第二高的薪水
- Leetcode 177. 第N高的薪水
- Leetcode 178. 分数排名
- Leetcode 180. 连续出现的数字
- Leetcode 181. 超过经理收入的员工
- Leetcode 182. 查找重复的电子邮箱
- Leetcode 183. 从不订购的客户
- Leetcode 184. 部门工资最高的员工
- Leetcode 185. 部门工资前三高的所有员工
- Leetcode 196. 删除重复的电子邮箱(自连接、删除语句)
- Leetcode 197. 上升的温度
- Leetcode 262. 行程和用户
- Leetcode 595. 大的国家
- Leetcode 596. 超过5名学生的课
- Leetcode 601. 体育馆的人流量
- Leetcode 620. 有趣的电影
- Leetcode 626. 换座位
- Leetcode 627. 交换工资
还没有评论,来说两句吧...