LeetCode “连续天数” 主题 SQL 题目汇总
这类问题通常要求识别出连续发生某事件的记录,是 SQL 面试中的高频题型。核心解法通常涉及窗口函数、自连接或者巧妙的分组技巧。
题目编号 | 题目名称 (英文) | 题目名称 (中文) | 核心解法/考察点 |
---|---|---|---|
180 | Consecutive Numbers | 连续出现的数字 | 基础/入门: 找到连续出现至少三次的数字。虽然不是日期,但解题逻辑完全相同,是 “连续性” 问题的入门必做题。通常使用 LAG() / LEAD() 或自连接来解决。 |
601 | Human Traffic of Stadium | 体育馆的人流量 | 经典: 找出连续三天或以上人流量超过 100 的记录。这是典型的 “寻找连续区间” 问题,需要识别出连续的 ID。可以使用窗口函数 ROW_NUMBER() 结合自连接,或者多次使用 LAG/LEAD。 |
1225 | Report Contiguous Dates | 报告连续的日期 | 经典: 给定成功和失败的日志,报告每个状态的连续日期范围。这是 “Gaps and Islands” (断点与岛屿) 问题的直接应用,最巧妙的解法是利用 ROW_NUMBER() 和日期的差值来创建一个分组标识。 |
1454 | Active Users | 活跃用户 | 经典: 找出连续 5 天登录的用户。和第 1225 题类似,也是 “Gaps and Islands” 问题。需要先对用户的登录日期去重,然后使用 DATE_SUB 和 ROW_NUMBER() 来创建分组。 |
1308 | Running Total for Different Genders | 不同性别学生的总分 | 相关概念: 虽然不是直接的 “连续天数”,但题目要求按性别和日期排序计算累计总分,考察了窗口函数中的 ORDER BY 和 PARTITION BY,这是解决连续性问题的基础。 |
1321 | Restaurant Growth | 餐馆营业额变化 | 相关概念: 计算 7 天的移动平均值。这涉及到对一个连续的日期窗口进行聚合操作 (SUM, AVG),也是处理连续日期数据的一种常见场景。 |
解决这类问题的通用技巧
- LAG() 和 LEAD() 函数:
- 这是最直观的方法,用于访问上一行或下一行的数据。
- 适用于判断 “连续 N 次” 的简单场景(例如 N=3)。当 N 很大时,需要进行多次自连接,代码会变得复杂。
- “Gaps and Islands” (断点与岛屿) 技巧:
- 这是解决复杂连续性问题的 最核心、最强大的技巧。
- 基本思想: 通过一个固定的日期序列减去一个递增的数字序列,为 “连续的” 记录创造出一个唯一的分组标识。
- 实现: DATE_SUB(your_date, INTERVAL ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY your_date) DAY)。对于同一个用户的连续日期,这个计算结果是相同的,因此可以 GROUP BY 这个结果来统计连续天数。
建议您按照表格中的顺序进行练习,从基础的 LAG() 函数应用开始,逐步掌握 “Gaps and Islands” 这一核心技巧。祝您刷题愉快!
This post is licensed under CC BY 4.0 by the author.