多属性行顺序不定且可能缺失,如何对齐为带最大时间的单行宽表
行转列合并时序属性数据的实现方案
问题分析
你之前使用NTILE分桶的方案依赖固定的属性数量和出现顺序,遇到属性缺失、顺序乱序的场景自然会出错,核心问题是没有基于属性本身的时序特征做分组。
解决方案
推荐使用属性独立排序+分组聚合的方案,实现如下:
实现逻辑
- 对每个属性(Weight/Count/Number)单独按时间升序排序,生成各自的行号,行号相同的属性属于同一批次
- 按行号分组,用case行转列提取各属性值,同时取该组最大的时间作为行时间
代码实现
WITH attribute_group AS ( SELECT Name, Value, Datetime, -- 同属性按时间排序,相同序号归为同一组 ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Datetime) AS group_id FROM #SourceTable ) SELECT MAX(Datetime) AS Datetime, MAX(CASE WHEN Name = 'Number' THEN Value END) AS Number, MAX(CASE WHEN Name = 'Count' THEN Value END) AS Count, MAX(CASE WHEN Name = 'Weight' THEN Value END) AS Weight FROM attribute_group GROUP BY group_id ORDER BY group_id;
方案优势
- 不依赖原始数据的属性出现顺序,适配乱序场景
- 自动兼容属性缺失:某组缺少Weight时,Weight列自动返回NULL,不会打乱分组逻辑
- 无需提前计算分桶数,不依赖自增ID,稳定性更高
可选适配方案(按Number触发分组)
如果你的分组逻辑是每生成一条Number记录就算新的一组,该Number之前、上一个Number之后的所有属性都归为当前组,可以用下面的分组逻辑:
WITH attribute_group AS ( SELECT Name, Value, Datetime, -- 遇到Number就新增组号 SUM(CASE WHEN Name = 'Number' THEN 1 ELSE 0 END) OVER(ORDER BY Datetime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS group_id FROM #SourceTable ) -- 后续聚合逻辑和上述方案一致
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

