题目描述

(通过次数11,888 | 提交次数31,865,通过率37.31%)

Activity 表:
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| user_id       | int     |
| session_id    | int     |
| activity_date | date    |
| activity_type | enum    |
+---------------+---------+
该表没有主键,它可能有重复的行。
activity_type 列是 ENUM 类型,可以取(“ open_session”,“ end_session”,“ scroll_down”,“ send_message”)四种活动类型之一。
该表显示了社交媒体网站的用户活动。
请注意,每个会话只属于一个用户。

编写 SQL 查询以查找截至 2019-07-27(含)的 30 天内每个用户的平均会话数,四舍五入到小数点后两位。只统计那些会话期间用户至少进行一项活动的有效会话。
查询结果格式如下例所示。
示例:
输入:
Activity 表:
+---------+------------+---------------+---------------+
| 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   |
| 3       | 5          | 2019-07-21    | open_session  |
| 3       | 5          | 2019-07-21    | scroll_down   |
| 3       | 5          | 2019-07-21    | end_session   |
| 4       | 3          | 2019-06-25    | open_session  |
| 4       | 3          | 2019-06-25    | end_session   |
+---------+------------+---------------+---------------+
输出:
+---------------------------+ 
| average_sessions_per_user |
+---------------------------+ 
| 1.33                      |
+---------------------------+
解释:用户 1 和 2 每人在过去 30 天有 1 个会话,而用户 3 有 2 个会话。所以平均是 (1 + 1 + 2) / 3 = 1.33 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/user-activity-for-the-past-30-days-ii
//测试数据
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 (user_id, session_id, activity_date, activity_type) values ('1', '1', '2019-07-20', 'open_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('1', '1', '2019-07-20', 'scroll_down');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('1', '1', '2019-07-20', 'end_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('2', '4', '2019-07-20', 'open_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('2', '4', '2019-07-21', 'send_message');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('2', '4', '2019-07-21', 'end_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '2', '2019-07-21', 'open_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '2', '2019-07-21', 'send_message');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '2', '2019-07-21', 'end_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '5', '2019-07-21', 'open_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '5', '2019-07-21', 'scroll_down');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('3', '5', '2019-07-21', 'end_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('4', '3', '2019-06-25', 'open_session');
insert into Activity (user_id, session_id, activity_date, activity_type) values ('4', '3', '2019-06-25', 'end_session');

解题思路

Activity表保存了用户所有的活动明细。不同的活动,可能归属于同一个会话;但同一个会话只归属于同一个用户。

题目要求:计算2019-07-27(含)的 30 天内每个用户的平均会话数。

首先,需要按时间筛选出这段时间内的明细数据。

然后,分别计算出这段时间内,总的用户数和会话数。因为用户和会话都可能会重复,所以在计算数量时,都需要去重。

最后,两者两除,得出平均会话数。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
    round(count(distinct session_id)/count(distinct user_id),2) average_sessions_per_user
from Activity
where activity_date between date_add('2019-07-27',interval -29 day) and '2019-07-27';
picture loss