如何将同一relId对应的多行不同edition合并为多列?
解决方案:行转列实现多edition横向展示
要实现将每个relId对应的多个edition转为横向列的需求,可以通过窗口函数生成序号+条件聚合的方式完成,兼容性好且逻辑清晰,以下是具体实现:
步骤1:为每个relId下的edition分配序号
先使用ROW_NUMBER()窗口函数,按relId分组、edition排序,给每个edition分配唯一序号:
SELECT relId, edition, ROW_NUMBER() OVER (PARTITION BY relId ORDER BY edition) AS rn FROM your_table_name;
执行后会得到这样的中间结果:
| relId | edition | rn |
|---|---|---|
| 1258 | B02 | 1 |
| 1258 | B03 | 2 |
| 4233 | B03 | 1 |
步骤2:条件聚合生成目标列
基于上述中间结果,用CASE WHEN配合MAX()函数,将不同序号的edition映射到对应的横向列:
SELECT relId, MAX(CASE WHEN rn = 1 THEN edition END) AS edition1, MAX(CASE WHEN rn = 2 THEN edition END) AS edition2 FROM ( SELECT relId, edition, ROW_NUMBER() OVER (PARTITION BY relId ORDER BY edition) AS rn FROM your_table_name ) t GROUP BY relId;
执行后即可得到你期望的结果:
| relId | edition1 | edition2 |
|---|---|---|
| 1258 | B02 | B03 |
| 4233 | B03 | NULL |
可选:用PIVOT语法简化(部分数据库支持)
如果你使用的是SQL Server、Oracle等支持PIVOT语法的数据库,也可以用以下写法:
SELECT relId, [1] AS edition1, [2] AS edition2 FROM ( SELECT relId, edition, ROW_NUMBER() OVER (PARTITION BY relId ORDER BY edition) AS rn FROM your_table_name ) t PIVOT ( MAX(edition) FOR rn IN ([1], [2]) ) p;
关于你之前的尝试
自连接+GROUP BY失败的原因通常是没有精准定位每个relId下的不同edition,比如自连接时容易出现重复匹配或无法区分多个edition的位置,而窗口函数生成序号的方式能明确每个edition的位置,再通过聚合就能准确映射到目标列。
内容的提问来源于stack exchange,提问作者Jan Willem de Lange
相关产品推荐
相关产品推荐

