1141. 查询近30天活跃用户数
1141. 查询近30天活跃用户数
难度:简单 | 题号:1141 | 链接:1141. 查询近30天活跃用户数 - 力扣(LeetCode) | 数据结构:SQL
关联:订单最多的用户(同为「按维度分组计数」)· 每月交易 I(同为日期函数 + 分组聚合)· 可对照 SQL原理_02(日期函数 / 分组聚合)。
🎯 问题描述
描述:写一条 SQL 查询,求出截至 2019-07-27(含)的近 30 天内,每天的活跃用户数。活跃用户指当天至少进行一次活动的用户,返回结果表的列名须为 day 和 active_users,且每天都可能出现重复用户(同一用户一天多次活动只算一次)。
表:Activity
1 | +---------------+---------+ |
示例 1:
1 | 输入: |
提示:
- 窗口是「左闭右开」的滑窗:
activity_date落在[2019-06-28, 2019-07-27]之间,即DATEDIFF('2019-07-27', activity_date) < 30(等价于<= 29)。 - 同一天同一用户多次活动只能计一次 → 必须
COUNT(DISTINCT user_id)。 - 结果按天分组,列名严格为
day/active_users(active_users是保留歧义最小的别名,建议加反引号或双引号)。
💻 解题思路
思路1:WHERE 筛日期 + 按天分组去重计数(用户解法)
核心逻辑
三步走:① WHERE 用 DATEDIFF 把数据裁到近 30 天窗口;② GROUP BY activity_date 按天分组;③ COUNT(DISTINCT user_id) 数出当天不重复的活跃用户数,并把日期列取别名为 day。
代码实现
1 | # Write your MySQL query statement below |
💡 精简写法:
BETWEEN '2019-06-28' AND '2019-07-27'更直观(右边界含 27 号,左边界 28 号正好 30 天);用DATEDIFF的好处是无需手算起始日期。
📊 性能分析
- 时间复杂度:(扫描全表 + 分组聚合;
activity_date上有索引时可先 range scan 裁剪数据量)。 - 空间复杂度:, 为不同日期数(分组哈希表规模)。
思考
- 别用
>= 30:DATEDIFF('2019-07-27', '2019-06-27') = 30,已经出界;< 30或<= 29才是「近 30 天」。 - 本题是滑动窗口计数的模板:先用日期函数把窗口裁出来,再分组去重计数。同类场景:日活 / 周活 / 月活(DAU/WAU/MAU)。
- 若题目改成「近 30 天总体活跃用户数」,就要去掉
GROUP BY,直接COUNT(DISTINCT user_id)。
🔗 相关链接
- 所属 MOC:学习-数据结构与算法MOC
- 题集索引:LeetCode题集索引
- 关联概念:SQL原理_02(日期函数 / 分组聚合)
- 同类题目:每月交易 I · 订单最多的用户
📝 总结
「滑动窗口 + 按维度去重计数」模板:
- 用
DATEDIFF(ref_date, date_col) < N或BETWEEN ... AND ...裁出窗口 →GROUP BY 日期→COUNT(DISTINCT 用户)。 - 两个易错点:① 窗口边界左闭右开(
< 30不是<= 30);② 同一用户同一天多次活动必须DISTINCT。
🔗 题集索引:LeetCode题集索引 · 算法地图:学习-数据结构与算法MOC
📎 同类题:每月交易 I · 订单最多的用户 | 概念:SQL原理_02
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






