Snowflake中如何用SQL合并多行生成宽表?
行转列实现事件主体合并为单行
你需要的是将同一事件下的多个主体(PARTY)从多行转成单行的多列,这属于典型的**行转列(透视表)**需求,完全可以实现。以下是具体解决方案:
实现思路
- 给每个事件(INCIDENT_ID)下的主体分配唯一序号:用窗口函数
ROW_NUMBER()按事件分组,给每个PARTY标记1-4的序号(因为最多4个主体)。 - 基于序号做条件聚合:将不同序号的PARTY_ID映射到对应的列(PARTY_ID、PARTY_ID2、PARTY_ID3、PARTY_ID4)。
完整SQL代码
SELECT I.INCIDENT_ID, I.INCIDENT_DATE, I.INCIDENT_POSTCODE, MAX(CASE WHEN rn = 1 THEN PA.PARTY_ID END) AS PARTY_ID, MAX(CASE WHEN rn = 2 THEN PA.PARTY_ID END) AS PARTY_ID2, MAX(CASE WHEN rn = 3 THEN PA.PARTY_ID END) AS PARTY_ID3, MAX(CASE WHEN rn = 4 THEN PA.PARTY_ID END) AS PARTY_ID4 FROM INCIDENT I INNER JOIN ( -- 给每个事件下的主体分配序号 SELECT INCIDENT_ID, PARTY_ID, ROW_NUMBER() OVER (PARTITION BY INCIDENT_ID ORDER BY PARTY_ID) AS rn FROM PARTY ) PA ON PA.INCIDENT_ID = I.INCIDENT_ID GROUP BY I.INCIDENT_ID, I.INCIDENT_DATE, I.INCIDENT_POSTCODE;
代码说明
- 子查询中的
ROW_NUMBER() OVER (PARTITION BY INCIDENT_ID ORDER BY PARTY_ID):按事件分组,给每个主体按PARTY_ID排序后分配序号。如果需要按其他规则排序(比如主体参与时间),修改ORDER BY后的字段即可。 - 外层的
MAX(CASE ...):针对每个序号提取对应的PARTY_ID,用MAX(或MIN,因为每个序号对应唯一值)聚合保留非空值,最终每个事件只会返回一行。 - 若某个事件的主体不足4个,对应的PARTY_ID列会显示为
NULL,符合宽表的常规逻辑。
内容的提问来源于stack exchange,提问作者tcotts
相关产品推荐
相关产品推荐

