如何通过SQL获取首字段为wire_open、wire_close的数据分组
需求说明
源数据集为用户状态时序记录,需按照蓝线标注规则处理:同一用户维度下,按日期排序后连续出现的相同状态记录合并为单条,输出每个连续状态段的用户ID、段起始日期、段结束日期、对应状态值,输出结构匹配预期效果。
实现SQL
以下写法兼容所有支持窗口函数的SQL引擎(MySQL 8.0+、PostgreSQL、SQL Server、Hive、Spark SQL等):
WITH temp_group AS ( SELECT user_id, event_date, status, -- 差值相同的记录属于同一个连续状态段 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY event_date) - ROW_NUMBER() OVER (PARTITION BY user_id, status ORDER BY event_date) AS continuous_group_id FROM your_source_table -- 替换为实际使用的源表名 ) SELECT user_id, MIN(event_date) AS start_date, MAX(event_date) AS end_date, status FROM temp_group GROUP BY user_id, status, continuous_group_id ORDER BY user_id, start_date;
逻辑解释
该写法是SQL处理连续段问题的经典「孤岛问题(Gaps and Islands)」通用解法:
- 先给每个用户的所有记录按日期升序打全局行号,再给每个用户下不同状态的记录分别按日期升序打状态内行号
- 两个行号的差值在连续相同状态的记录中是固定值,非连续的相同状态差值会发生变化,用这个差值就可以给每个连续状态段生成唯一标识
- 最后按用户、状态、连续段标识分组,聚合取段内最早日期为起始时间、最晚日期为结束时间,即可得到要求的输出结果。
内容的提问来源于stack exchange,提问作者vaibhav
相关产品推荐
相关产品推荐

