1141. 查询近30天活跃用户数

标签:distinct,时间函数

2022年12月18日

题目

活动记录表:Activity

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| user_id       | int     |
| session_id    | int     |
| activity_date | date    |
| activity_type | enum    |
+---------------+---------+
该表是用户在社交网站的活动记录。
该表没有主键,可能包含重复数据。
activity_type 字段为以下四种值 ('open_session', 'end_session', 'scroll_down', 'send_message')。
每个 session_id 只属于一个用户。

请写SQL查询出截至 2019-07-27(包含2019-07-27),近 30 天的每日活跃用户数(当天只要有一条活动记录,即为活跃用户)。

任意顺序 返回结果表。

查询结果示例如下。

示例 1:

输入:
Activity table:
+---------+------------+---------------+---------------+
| user_id | session_id | activity_date | activity_type |
+---------+------------+---------------+---------------+
| 1       | 1          | 2019-07-20    | open_session  |
| 1       | 1          | 2019-07-20    | scroll_down   |
| 1       | 1          | 2019-07-20    | end_session   |
| 2       | 4          | 2019-07-20    | open_session  |
| 2       | 4          | 2019-07-21    | send_message  |
| 2       | 4          | 2019-07-21    | end_session   |
| 3       | 2          | 2019-07-21    | open_session  |
| 3       | 2          | 2019-07-21    | send_message  |
| 3       | 2          | 2019-07-21    | end_session   |
| 4       | 3          | 2019-06-25    | open_session  |
| 4       | 3          | 2019-06-25    | end_session   |
+---------+------------+---------------+---------------+
输出:
+------------+--------------+ 
| day        | active_users |
+------------+--------------+ 
| 2019-07-20 | 2            |
| 2019-07-21 | 2            |
+------------+--------------+ 
解释:注意非活跃用户的记录不需要展示。

思路:

  1. 先找出复合时间条件的记录(即2019年7月27号前30天的数据)

  2. 再根据找出来的每一天的数据的user_id进行去重(distinct)后计数(count)(因为一个用户可能会一天内访问多次)


方法一

使用日期的减法(subdate

# Write your MySQL query statement below
select
     activity_date as day,count(distinct user_id) as active_users
from 
    Activity
group by
    activity_date
having
    activity_date > subdate('2019-07-27',30) and activity_date <='2019-07-27'

mysql中date_sub(date,INTERVAL expr type) 和 subdate(date,INTERVAL expr type) 两个函数作用相同,都是执行日期的减法运算

date_sub() 和subdate() 函数接受两个参数:

  • date 是 date 或 datetime 的起始值。
  • expr 是一个字符串,用于确定从起始日期减去的间隔值。type 是 expr 可解析的间隔单位,例如 day,hour 等

两者的小区别:

  • subdate:可以省略intervaltype,如果只写一个数字默认的单位是天
  • date_sub:不可省略intervaltype,会报错

示例:

select subdate('1999-01-01', 1)
+---------------------------------------------------------+
| subdate('1999-01-01',1)                  |
+---------------------------------------------------------+
| 1998-01-01                                              |
+---------------------------------------------------------+


select date_sub('1999-01-01',interval 1 year)
+---------------------------------------------------------+
| date_sub('1999-01-01',interval 1 year)                   |
+---------------------------------------------------------+
| 1998-01-01                                              |
+---------------------------------------------------------+


方法二

使用between操作符和date函数

select 
    activity_date as day, count(distinct user_id) as active_users
from 
    Activity
where 
    activity_date between date('2019-06-28') and date('2019-07-27')
group by
     activity_date;

版权声明:本文为woshhhk原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。