当前位置: 首页 > web >正文

SQL实战:05之间隔连续数问题求解

概述

最近刷题时遇到一些比较有意思的题目,之前多次遇到一些求解连续数的问题,这次遇到了他们的变种,连续数可以间隔指定的数也视为是一个完整的“连续”。针对连续数的这类问题我们之前讲的可以利用等差数列的思想来解决,然而现在发生了变形一定还能继续使用等差数列来解决吗?答案是否定的,针对带有指定间隔的连续数问题应当使用分组问题的思想来解决。

题目:间隔连续表

某游戏公司记录的用户每日登录数据

表logs

字段名数据类型
idbigint
dtdate

输入数据如下:

iddt
10012021/12/12
10022021/12/12
10012021/12/13
10012021/12/14
10012021/12/16
10022021/12/16
10012021/12/19
10022021/12/17
10012021/12/20

计算每个用户最大的连续登录天数,可以间隔一天。解释:如果一个用户在 1,3,5,6 登
录游戏,则视为连续 6 天登录。

题解

第一步:下移数据

WITH temp_001 AS (SELECT id,dt,LAG(dt,1,'1970-01-01') OVER (PARTITION BY id ORDER BY dt ASC) AS prev_dtFROM logs
)

输出如下:

iddtprev_dt
10012021/12/121970/01/01
10012021/12/132021/12/12
10012021/12/142021/12/13
10012021/12/162021/12/14
10012021/12/192021/12/19
10012021/12/202021/12/20
10022021/12/121970/01/01
10022021/12/162021/12/12
10022021/12/172021/12/16

步骤二:窗口分组累加

计算当前日期和上一日期的差值,如果差值小于等于2,则认为是同一组组号不变,如果差值大于2则任务是新的组,组号+1.
SQL实现:

temp_002 AS (SELECT id,dt,SUM(IF(DATEDIFF(dt,prev_dt)>2,1,0)) OVER(PARTITION BY id ORDER BY dt ASC) AS group_idFROM temp_001
)

输出结果:

iddtgroup_id
10012021/12/121
10012021/12/131
10012021/12/141
10012021/12/161
10012021/12/192
10012021/12/202
10022021/12/121
10022021/12/162
10022021/12/172

步骤三:根据id和group分组统计出最大、最小日期

temp_003 AS (SELECT id,group_id,min(dt) as min_dt,max(dt) as max_dtFROM temp_002GROUP BY id,group_id
)

输出结果

idgroup_idmin_dtmax_dt
100112021/12/122021/12/16
100122021/12/192021/12/20
100212021/12/122021/12/12
100222021/12/162021/12/17

步骤四:使用最大日期减掉最小日期再加1,就可以得到每一组的最大连续天数

temp_004 AS (SELECT id,group_id,min_dt,max_dt,datediff(max_dt,min_dt) + 1 AS daysFROM temp_003
)

输出结果

idgroup_idmin_dtmax_dtdays
100112021/12/122021/12/165
100122021/12/192021/12/202
100212021/12/122021/12/121
100222021/12/162021/12/172

步骤五: 在取每个id的最大连续天数得到最终结果

SELECT id,max(days) as days from temp_004 group by id;

完整SQL

WITH temp_001 AS (SELECT id,dt,LAG(dt,1,'1970-01-01') OVER (PARTITION BY id ORDER BY dt ASC) AS prev_dtFROM logs
)
,temp_002 AS (SELECT id,dt,SUM(IF(DATEDIFF(dt,prev_dt)>2,1,0)) OVER(PARTITION BY id ORDER BY dt ASC) AS group_idFROM temp_001
)
,temp_003 AS (SELECT id,group_id,min(dt) as min_dt,max(dt) as max_dtFROM temp_002GROUP BY id,group_id
)
,temp_004 AS (SELECT id,group_id,min_dt,max_dt,datediff(max_dt,min_dt) + 1 AS daysFROM temp_003
)
SELECT id,max(days) as days from temp_004 group by id;
http://www.xdnf.cn/news/3241.html

相关文章:

  • 安全企业内部im,BeeWorks即时通讯
  • boost 编译(windows10 + mingw7.3.0)
  • EWM 流程全自动化实现方法
  • 华为发布全球首个L3商用智驾ADS4.0
  • SpringBoot 设置HTTP代理访问
  • Wartales 战争传说 [DLC 解锁] [Steam] [Windows SteamOS]
  • transformers库里model.generate和model.forward的区别 generate函数里不同的解码方式
  • 【MyBatis-Plus】禁用某个方法里面查询语句的逻辑删除标记
  • Java 中的 设计模式详解
  • errorno 和WSAGetlasterror的区别
  • 潇洒郎: 100% 成功搭建Docker私有镜像仓库并管理、删除镜像
  • Pytorch深度学习框架60天进阶学习计划 - 第55天:3D视觉基础(一)
  • 【人工智能】释放本地AI潜能:LM Studio用户脚本自动化DeepSeek的实战指南
  • (A2A Agent通信故障诊断体系)
  • Spring Boot 数据库最佳实践:从自动配置到高性能优化
  • 腾讯云CodeBuddy初体验
  • 从边缘到云端:边缘计算与云计算的协同未来
  • OpenCV-Python (官方)中文教程(部分一)_Day20
  • Elastic Security 8.18 和 9.0 中的新功能
  • Vue 3 动态组件
  • PostgreSQL可串行化快照隔离和冻结处理
  • 农产品园区展示系统——仙盟创梦IDE开发
  • 《PyTorch documentation》(PyTorch 文档)
  • vscode 个性化
  • 通过API网关防御重放攻击:技术方案与实战验证
  • 规划权重和全局优化器逻辑处理
  • 基于C++的IOT网关和平台5:github项目ctGateway开发指南
  • MyBatis的SQL映射文件中,`#`和`$`符号的区别
  • 大数据治理自动化与智能化实践指南:架构、工具与实战方案(含代码)
  • Oracle Bigfile 与 Smallfile 表空间对比分析