1.每日SQL----2024/11/7

题目:

计算用户次日留存率,即用户第二天继续登录的概率

表:

id device_id date
1 2138 2024-05-03
2 3214 2024-05-09
3 3214 2024-06-15
4 6543 2024-08-13
5 2315 2024-08-13
6 2315 2024-08-14
7 2315 2024-08-15
8 3214 2024-05-09
9 3214 2024-08-15
10 6543 2024-08-13
11 2315 2024-08-13
12 2315 2024-08-14
13 2315 2024-08-15
14 3214 2024-08-16
15 3214 2024-08-18
16 6543 2024-08-13
  • id 用户唯一标识符
  • device_id 用户登录使用的设备标识符
  • date 用户登录日期

你应该返回的结果:

avg_ret
0.3000

请认真思考后作答


解题思路

  1. 去重数据:首先,我们需要从原始数据中选择每个设备ID (device_id) 和对应的登录日期 (date),并去除重复项。这一步是为了确保每个设备在每个日期只有一条记录。

  2. 查找下一个登录日期:使用窗口函数 LEAD(),我们可以找到每个设备的下一个登录日期。LEAD() 函数会返回当前行之后的指定偏移量的行的值。这里我们将 LEAD() 应用在 date 列上,按 device_id 分区,并按 date 排序。

  3. 计算日期差:对于每一对连续的登录日期(当前日期 date1 和下一个日期 date2),我们使用 DATEDIFF() 函数计算它们之间的天数差。如果天数差为1,则表示用户在次日登录了。

  4. 计算次日留存率:使用 IF 语句,如果 DATEDIFF(date2, date1) = 1,则返回1,否则返回0。然后,对所有的这些0和1取平均值,得到次日留存率。

代码如下

sql 复制代码
select avg(if(datediff(date2, date1)=1, 1, 0)) as avg_ret
from (
    select
        distinct device_id,
        date as date1,
        lead(date) over (partition by device_id order by date) as date2
    from (
        select distinct device_id, date
        from user_detail
    ) as uniq_id_date
) as id_last_next_date

运行结果如下

本题的重点是lead开窗函数的使用,你学会了吗?下期见~

后附建表语句

sql 复制代码
drop table if  exists `user_detail`;
CREATE TABLE `user_detail` (
`id` int NOT NULL,
`device_id` int NOT NULL,
`date` date NOT NULL
);

INSERT INTO user_detail VALUES(1,2138,'2024-05-03');
INSERT INTO user_detail VALUES(2,3214,'2024-05-09');
INSERT INTO user_detail VALUES(3,3214,'2024-06-15');
INSERT INTO user_detail VALUES(4,6543,'2024-08-13');
INSERT INTO user_detail VALUES(5,2315,'2024-08-13');
INSERT INTO user_detail VALUES(6,2315,'2024-08-14');
INSERT INTO user_detail VALUES(7,2315,'2024-08-15');
INSERT INTO user_detail VALUES(8,3214,'2024-05-09');
INSERT INTO user_detail VALUES(9,3214,'2024-08-15');
INSERT INTO user_detail VALUES(10,6543,'2024-08-13');
INSERT INTO user_detail VALUES(11,2315,'2024-08-13');
INSERT INTO user_detail VALUES(12,2315,'2024-08-14');
INSERT INTO user_detail VALUES(13,2315,'2024-08-15');
INSERT INTO user_detail VALUES(14,3214,'2024-08-16');
INSERT INTO user_detail VALUES(15,3214,'2024-08-18');
INSERT INTO user_detail VALUES(16,6543,'2024-08-13');
相关推荐
建投数据25 分钟前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi1 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀1 小时前
Redis梳理
数据库·redis·缓存
独行soc1 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天2 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
工业甲酰苯胺2 小时前
分布式系统架构:服务容错
数据库·架构
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain4 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship4 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站4 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle