Leetcode Database 刷题

左手的ㄟ右手 2021-10-15 12:21 751阅读 0赞

文章目录

    1. 组合两个表
    1. 第二高的薪水
    1. 第N高的薪水
    1. 分数排名
    1. 连续出现的数字
    1. 超过经理收入的员工
    1. 查找重复的电子邮箱
    1. 从不订购的客户
    1. 部门工资最高的员工
    1. 部门工资前三高的所有员工
    1. 删除重复的电子邮箱(自连接、删除语句)
    1. 上升的温度
    1. 行程和用户
    1. 大的国家
    1. 超过5名学生的课
    1. 育馆的人流量
    1. 有趣的电影
    1. 换座位
    1. 交换工资

175. 组合两个表

左连接

  1. SELECT
  2. p.FirstName,
  3. p.LastName,
  4. a.City,
  5. a.State
  6. FROM
  7. Person p LEFT JOIN Address a
  8. ON
  9. p.PersonId = a.PersonId

176. 第二高的薪水

子查询

ifnull() 函数

  1. SELECT
  2. ifnull(
  3. (
  4. SELECT DISTINCT
  5. Salary
  6. FROM
  7. Employee
  8. ORDER BY
  9. Salary
  10. DESC
  11. LIMIT 1, 1
  12. ),
  13. NULL
  14. )
  15. AS SecondHighestSalary
  16. SELECT
  17. (
  18. SELECT DISTINCT
  19. Salary
  20. FROM
  21. Employee
  22. ORDER BY
  23. Salary
  24. DESC
  25. LIMIT 1, 1
  26. )
  27. AS SecondHighestSalary

177. 第N高的薪水

178. 分数排名

180. 连续出现的数字

自连接

如果一个数字连续出现超过 3 次,会返回重复元素,需要使用 DISTINCT 去重。

  1. SELECT DISTINCT
  2. l1.Num AS ConsecutiveNums
  3. FROM
  4. `Logs` l1,
  5. `Logs` l2,
  6. `Logs` l3
  7. WHERE
  8. l1.Num = l2.Num AND l2.Num = l3.Num AND l1.Id = l2.Id - 1 AND l2.Id = l3.Id - 1

181. 超过经理收入的员工

  1. SELECT
  2. e1.NAME AS Employee
  3. FROM
  4. Employee e1,
  5. Employee e2
  6. WHERE
  7. e1.ManagerId = e2.Id
  8. AND e1.Salary > e2.Salary

182. 查找重复的电子邮箱

分组聚合

  1. SELECT
  2. Email
  3. FROM
  4. Person
  5. GROUP BY
  6. Email
  7. HAVING
  8. count(Email) > 1

183. 从不订购的客户

  1. 左连接

    SELECT

    1. NAME AS Customers

    FROM

    1. Customers c LEFT JOIN Orders o ON c.Id = o.CustomerId

    WHERE

    1. o.Id IS NULL
  2. 范围查询

    SELECT

    1. Name AS Customers

    FROM

    1. Customers

    WHERE

    1. Customers.Id NOT IN (SELECT CustomerId FROM Orders)

184. 部门工资最高的员工

  1. 内连接 + 范围查询

    SELECT

    1. d.NAME AS Department,
    2. e.NAME AS Employee,
    3. e.Salary

    FROM

    1. Employee e,
    2. Department d

    WHERE

    1. e.DepartmentId = d.Id
    2. AND (e.DepartmentId, Salary) IN (
    3. SELECT
    4. DepartmentId,
    5. MAX(Salary)
    6. FROM
    7. Employee
    8. GROUP BY
    9. DepartmentId
    10. )
  2. 内连接 + 子查询

    SELECT

    1. d.NAME AS Department,
    2. e.NAME AS Employee,
    3. e.Salary

    FROM

    1. Employee e,
    2. Department d,
    3. (
    4. SELECT
    5. DepartmentId,
    6. MAX(Salary) AS salary
    7. FROM
    8. Employee
    9. GROUP BY
    10. DepartmentId
    11. ) AS t

    WHERE

    1. e.DepartmentId = d.Id
    2. AND e.DepartmentId = t.DepartmentId
    3. AND e.Salary = t.Salary

185. 部门工资前三高的所有员工

  1. 重复薪水的处理

    员工的薪水可能相同,前三高工资的记录数可能大于 3,使用 ORDER BY Salary DESC LIMIT 3 无法满足题目要求。

    并且,本题中相同工资视为同一排名,不会挤占后面的排位。例如 [200, 150, 150, 100, 90],前三高为 [200, 150, 150, 100],而不是 [200, 150, 150]。因此,使用 COUNT(DISTINCT e2.Salary) 去除重复工资的计数。

  2. 子查询

    将子查询结果作为筛选条件,产生类似遍历的效果。在本题中,对于员工表中的每一条记录,通过子查询查找出同一部门中工资高于该记录的员工数,从而判断该记录是否符合前三高条件,完成条件筛选。

  3. 分组聚合

    一般地,聚合函数与 GROUP BYHAVING 配合使用。聚合函数作为筛选条件时,只能出现在 HAVING 语句中。聚合函数作为查询结果时,可以单独出现在 SELECT 语句中,此时默认分组是整个表。

    本题中,筛选条件是员工数量,而又不便于划分分组,不得不采用子查询的写法。

  4. 连接的条件筛选

    ON 用于在生成临时表时的条件筛选;WHERE 用于对已生成的临时表进行条件筛选。

    以左连接为例,不论 ON 中的条件是否为真,都会返回左表中的记录,即 ON 条件对左表无效。而 WHERE 作用于临时表,对来自各表中的字段一视同仁。

    对于内连接,ON 要求各表都满足筛选条件,原理上与 WHERE 作用对象不同,效果上却是完全相同。因此,内连接中 ON 可以替代 WHERE,反之不行。实践中,一般使用 ON …… AND …… 而很少用到 ON …… WHERE ……

    SELECT

    1. d.NAME AS Department,
    2. e1.NAME AS Employee,
    3. e1.Salary

    FROM

    1. Employee e1 JOIN Department d

    ON

    1. e1.DepartmentId = d.Id

    AND

    1. 3 > (
    2. SELECT
    3. COUNT(DISTINCT e2.Salary)
    4. FROM
    5. Employee e2
    6. WHERE
    7. e2.Salary > e1.Salary AND e1.DepartmentId = e2.DepartmentId
    8. )

196. 删除重复的电子邮箱(自连接、删除语句)

自连接

多表连接删除:将需要执行操作的表名写在 DELETE 后面。这样,删除只影响部分表,但同时利用多张表进行查询。

  1. DELETE
  2. p1
  3. FROM
  4. Person p1,
  5. Person p2
  6. WHERE
  7. p1.Email = p2.Email AND p1.Id > p2.Id

197. 上升的温度

DATEDIFF() 用于计算两个日期值相差的天数,数据类型可以是 DATE、DATETIME 和 TIMESTAMP,对于 DATETIME 或 TIMESTAMP,该函数仅将日期部分用于计算,并忽略时间部分。

ADDDATE(date, INTERVAL 1 DAY) 对当前日期增加一定量的时间。

  1. SELECT
  2. w2.Id
  3. FROM
  4. Weather w1,
  5. Weather w2
  6. WHERE
  7. ADDDATE(w1.RecordDate, INTERVAL 1 DAY) = w2.RecordDate AND w1.Temperature < w2.Temperature
  8. SELECT
  9. w1.Id AS Id
  10. FROM
  11. Weather w1,
  12. Weather w2
  13. WHERE
  14. 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
  1. SELECT
  2. class
  3. FROM
  4. courses
  5. GROUP BY
  6. class
  7. HAVING
  8. count(DISTINCT student) >= 5

601. 育馆的人流量

620. 有趣的电影

MySQL 常用运算符及函数汇总:https://www.jb51.net/article/124096.htm

  1. SELECT
  2. *
  3. FROM
  4. cinema
  5. WHERE
  6. description <> 'boring' AND id % 2 = 1
  7. ORDER BY
  8. rating
  9. 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 错误,只能先通过子查询计算最大值,再进行条件筛选。

  1. SELECT
  2. CASE
  3. WHEN id % 2 = 0
  4. THEN id - 1
  5. WHEN id = (SELECT MAX(id) FROM seat)
  6. THEN id
  7. ELSE id + 1
  8. END AS id, student
  9. FROM
  10. seat
  11. ORDER BY
  12. id
  13. SELECT
  14. IF (
  15. id % 2 = 0,
  16. id - 1,
  17. IF (
  18. id = (SELECT MAX(id) FROM seat),
  19. id,
  20. id + 1
  21. )
  22. ) AS id, student
  23. FROM
  24. seat
  25. ORDER BY
  26. id

627. 交换工资

  1. 条件语句

    UPDATE

    1. salary

    SET

    1. sex =
    2. CASE sex
    3. WHEN 'm'
    4. THEN 'f'
    5. ELSE 'm'
    6. END

    UPDATE

    1. salary

    SET

    1. sex =
    2. IF (sex = 'f', 'm', 'f')
  2. 异或/加减交换

    UPDATE

    1. salary

    SET

    1. sex = CHAR (ASCII(sex) ^ ASCII('m') ^ ASCII('f'))

    UPDATE

    1. salary

    SET

    1. 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. 交换工资

发表评论

表情:
评论列表 (有 0 条评论,751人围观)

还没有评论,来说两句吧...

相关阅读

    相关 52LeetCode_LeetCode手册

    虽然刷题一直饱受诟病,不过不可否认刷题确实能锻炼我们的编程能力,相信每个认真刷题的人都会有体会。现在提供在线编程评测的平台有很多,比较有名的有 hihocoder,LintCo

    相关 LeetCode指南

    以下是我个人做题过程中的一些体会:  1. LeetCode的题库越来越大,截止到目前,已经有321个问题了。对于大多数人来说,没有时间也没有必要把所有题目都做一遍(时间充

    相关 Leetcode

    39. 组合总和 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。