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

327 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第33天,点击查看活动详情

一、题目

活动记录表: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            |
+------------+--------------+ 
解释:注意非活跃用户的记录不需要展示。
  • 来源:力扣(LeetCode)
  • 链接:leetcode.cn/problems/us…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、解题思路

创建数据表

CREATE TABLE IF NOT EXISTS Activity(
	user_id INT,
	session_id INT,
	activity_date DATE,
	activity_type ENUM('open_session', 'end_session', 'scroll_down', 'send_message')
);
INSERT INTO Activity VALUES
(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');

解题

  • 首根据题意,这里要筛选以日志为准的数据集,这里可以使用group by activity_date
  • 这里要近30天的记录,因此这里的条件是WHERE Activity.activity_date BETWEEN '2019-06-27' AND '2019-07-27',但是这个有点不够严谨,因此这里使用DATEDIFF判断小于30天内的时间同时要求时间要小于2019-07-27
  • 字段名称这里要修改activity_date为 DAY,第二个字段要计算用户的数量,因为有重复数据,这里要去重DISTINCT user_id,去重之后用COUNT计算,设置假名为active_users
  • 直接语句得到结果
SELECT
	activity_date DAY, COUNT(DISTINCT user_id) active_users
FROM
	Activity t
WHERE
	DATEDIFF('2019-07-27', t.activity_date) < 30 AND t.activity_date < '2019-07-27'
GROUP BY activity_date

image.png

三、执行语句

执行结果

image.png

四、总结

这里使用COUNT、DISTINCT、DATEDIFF、GROUP BY,分别用户计算用户数量,给用户去重,判断时间的范围以及对数据进行分组。加强对这些SQL函数的使用数据度。