用户行为日志表tb_user_log
id | uid | artical_id | in_time | out_time | sign_cin |
1 | 101 | 9001 | 2021-11-01 10:00:00 | 2021-11-01 10:00:31 | 0 |
2 | 102 | 9001 | 2021-11-01 10:00:00 | 2021-11-01 10:00:24 | 0 |
3 | 102 | 9002 | 2021-11-01 11:00:00 | 2021-11-01 11:00:11 | 0 |
4 | 101 | 9001 | 2021-11-02 10:00:00 | 2021-11-02 10:00:50 | 0 |
5 | 102 | 9002 | 2021-11-02 11:00:01 | 2021-11-02 11:00:24 | 0 |
(uid-用户ID, artical_id-文章ID, in_time-进入时间, out_time-离开时间, sign_in-是否签到)
场景逻辑说明:artical_id-文章ID代表用户浏览的文章的ID,artical_id-文章ID为0表示用户在非文章内容页(比如App内的列表页、活动页等)。
问题:统计2021年11月每天的人均浏览文章时长(秒数),结果保留1位小数,并按时长由短到长排序。
输出示例:
示例数据的输出结果如下
dt | avg_viiew_len_sec |
2021-11-01 | 33.0 |
2021-11-02 | 36.5 |
解释:
11月1日有2个人浏览文章,总共浏览时长为31+24+11=66秒,人均浏览33秒;
11月2日有2个人浏览文章,总共时长为50+23=73秒,人均时长为36.5秒。
示例1
输入:
DROP TABLE IF EXISTS tb_user_log; CREATE TABLE tb_user_log ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID', uid INT NOT NULL COMMENT '用户ID', artical_id INT NOT NULL COMMENT '视频ID', in_time datetime COMMENT '进入时间', out_time datetime COMMENT '离开时间', sign_in TINYINT DEFAULT 0 COMMENT '是否签到' ) CHARACTER SET utf8 COLLATE utf8_bin; INSERT INTO tb_user_log(uid, artical_id, in_time, out_time, sign_in) VALUES (101, 9001, '2021-11-01 10:00:00', '2021-11-01 10:00:31', 0), (102, 9001, '2021-11-01 10:00:00', '2021-11-01 10:00:24', 0), (102, 9002, '2021-11-01 11:00:00', '2021-11-01 11:00:11', 0), (101, 9001, '2021-11-02 10:00:00', '2021-11-02 10:00:50', 0), (102, 9002, '2021-11-02 11:00:01', '2021-11-02 11:00:24', 0);
复制输出:
2021-11-01|33.0 2021-11-02|36.5
简单分析:反正 我们只是针对说 artical_id 不等于 0 的用户 和 11 月份的数据
因为没有date 类型的数据,所以我们需要在in_time 里面弄出一个date 的值,这里要做一个转换
DATE_FORMAT(in_time,
"%Y%m"
) =
"202111"
因为求的是每天,所以我们可以知道一定是按每天来做group的,但又没有这个知道
所有我们只能自己用一个date 自段出来,比如 date(in_date) 作为group的
平均时间怎么求呢 -> 总的时间差数,是sum(out_time - in_time)
总的个数count(*)
问题分解:
- 计算每次文章浏览的时长和日期:
- 过滤目标时间窗的有效浏览记录:WHERE artical_id != 0 AND DATE_FORMAT(in_time, "%Y%m") = "202111"
- 将进入时间转化为日期:DATE(in_time) as dt
- 计算浏览时长:TIMESTAMPDIFF(SECOND, in_time, out_time) as view_len_sec
- 按日期分组:GROUP BY dt
- 计算人均时长(=总时长÷人数):SUM(view_len_sec) / COUNT(DISTINCT uid) as avg_view_len_sec
- 保留1位小数:ROUND(x, 1)
细节问题:
- 表头重命名:as
- 按时长由短到长排序:ORDER BY avg_view_len_sec
完整代码:
1 2 3 4 5 6 7 8 9 |
|