SQL 29 计算用户的平均次日留存率题解

问题截图如下:

SQL建表代码:

sql 复制代码
drop table if exists `user_profile`;
drop table if  exists `question_practice_detail`;
drop table if  exists `question_detail`;
CREATE TABLE `user_profile` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`gender` varchar(14) NOT NULL,
`age` int ,
`university` varchar(32) NOT NULL,
`gpa` float,
`active_days_within_30` int ,
`question_cnt` int ,
`answer_cnt` int 
);
CREATE TABLE `question_practice_detail` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`question_id`int NOT NULL,
`result` varchar(32) NOT NULL,
`date` date NOT NULL
);
CREATE TABLE `question_detail` (
`id` int NOT NULL,
`question_id`int NOT NULL,
`difficult_level` varchar(32) NOT NULL
);

INSERT INTO user_profile VALUES(1,2138,'male',21,'北京大学',3.4,7,2,12);
INSERT INTO user_profile VALUES(2,3214,'male',null,'复旦大学',4.0,15,5,25);
INSERT INTO user_profile VALUES(3,6543,'female',20,'北京大学',3.2,12,3,30);
INSERT INTO user_profile VALUES(4,2315,'female',23,'浙江大学',3.6,5,1,2);
INSERT INTO user_profile VALUES(5,5432,'male',25,'山东大学',3.8,20,15,70);
INSERT INTO user_profile VALUES(6,2131,'male',28,'山东大学',3.3,15,7,13);
INSERT INTO user_profile VALUES(7,4321,'male',28,'复旦大学',3.6,9,6,52);
INSERT INTO question_practice_detail VALUES(1,2138,111,'wrong','2021-05-03');
INSERT INTO question_practice_detail VALUES(2,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(3,3214,113,'wrong','2021-06-15');
INSERT INTO question_practice_detail VALUES(4,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(5,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(6,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(7,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(8,3214,112,'wrong','2021-05-09');
INSERT INTO question_practice_detail VALUES(9,3214,113,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(10,6543,111,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(11,2315,115,'right','2021-08-13');
INSERT INTO question_practice_detail VALUES(12,2315,116,'right','2021-08-14');
INSERT INTO question_practice_detail VALUES(13,2315,117,'wrong','2021-08-15');
INSERT INTO question_practice_detail VALUES(14,3214,112,'wrong','2021-08-16');
INSERT INTO question_practice_detail VALUES(15,3214,113,'wrong','2021-08-18');
INSERT INTO question_practice_detail VALUES(16,6543,111,'right','2021-08-13');
INSERT INTO question_detail VALUES(1,111,'hard');
INSERT INTO question_detail VALUES(2,112,'medium');
INSERT INTO question_detail VALUES(3,113,'easy');
INSERT INTO question_detail VALUES(4,115,'easy');
INSERT INTO question_detail VALUES(5,116,'medium');
INSERT INTO question_detail VALUES(6,117,'easy');

题目解析:该题目解法有多种,其中一种就是求出第二天的还在做题的人数量,并将其做成一个新的表格,再将其和第一天的相除,就得到了结果了。

题目解法:

sql 复制代码
select
    count(date2) / count(date1) as avg_ret
from
    (
        select distinct
            qpd.device_id,
            qpd.date as date1,
            uniq_id_date.date as date2
        from
            question_practice_detail as qpd
            left join (
                select distinct
                    device_id,
                    date
                from
                    question_practice_detail
            ) as uniq_id_date on qpd.device_id = uniq_id_date.device_id
            and date_add (qpd.date, interval 1 day) = uniq_id_date.date
    ) as id_last_next_date

这种解法的关键在我看来,就是date_add (qpd.date, interval 1 day) 这个函数,这个函数是将日期往后加一天的意思,这样就能查到同样设备的第二天的做题情况了。

DATE_ADD(qpd.date, INTERVAL 1 DAY) 表示将 qpd.date 所表示的日期增加 1 天。

DATE_ADD() 是 MySQL 中的一个日期函数,用于向指定的日期添加指定的时间间隔。其语法为:DATE_ADD(date, INTERVAL expr type),其中:

  • date:是合法的日期表达式,表示要操作的起始日期。
  • expr:表示要添加的时间间隔的值。
  • type:指定时间间隔的单位,可以是DAY(天)、HOUR(小时)、MINUTE(分钟)、SECOND(秒)、WEEK(周)、MONTH(月)、QUARTER(季度)、YEAR(年)等。

例如,如果当前 qpd.date 的值是 2024-06-28,那么 DATE_ADD(qpd.date, INTERVAL 1 DAY) 的结果将是 2024-06-29

相关推荐
kyriewen1 天前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
IT_陈寒1 天前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
小林攻城狮1 天前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦1 天前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer1 天前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队1 天前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY1 天前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_1 天前
OpenSpec 完整详细介绍
前端·后端
召钱熏1 天前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
SkyWalking中文站1 天前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控