思路:
题目要求:统计截至 2019-07-27
(包含2019-07-27
),近 30 天的每日活跃用户数(当天只要有一条活动记录,即为活跃用户)
要计算日期之间的天数,这时就需要用到datediff
函数
datediff(date1,date2)
:返回date1 - date2
的日期间隔天数
把在时间要求内的筛选出来,再进行 用户id 分组,最后统计用户个数(去重后的)
解题过程:
先对日期进行筛选
select * from activity where datediff('2019-07-27',activity_date) between 0 and 29
然后再日期进行分组,计算用户id,这时需要对用户id进行去重,若不去重,则会出现以下结果
select activity_date, count(user_id) from activity where datediff('2019-07-27',activity_date) between 0 and 29 group by activity_date
所以需要对用户id进行去重处理(count(distinct user_id
)保证每个用户不相同(或者说重复出现)
踩了个坑:
where datediff('2019-07-27',activity_date) between 0 and 29 group by activity_date
和
group by activity_date having datediff('2019-07-27',activity_date) between 0 and 29
提出问题,这两个mysql语句都可以执行成功,但两者一点问题都没有嘛?
一个先过滤后分组,另一个先分组后过滤。按理说没毛病啊
但是结果却是:
- 第一个查询是正确的,因为它使用where子句来过滤日期范围,然后使用group by和count(distinct user_id)来统计每日活跃用户数。
- 第二个查询错误地将日期范围过滤放在了having子句中,而没有使用聚合函数,这不符合sql语法。
- 正确的做法是在where子句中指定日期范围过滤条件,然后使用group by进行分组统计。
注意:having子句不能独立于聚合函数使用来过滤原始数据
发表评论