Oracle SQL:如何按ID将列数据转换为单行多列?
Oracle SQL实现按ID将多行数据转单行多列
在Oracle SQL里可以用Pivot结合行号函数实现你要的效果,你之前用Pivot没成功,核心原因是没给每个ID分组内的行分配唯一序号,具体实现如下:
步骤1:给每个ID下的行生成序号
先通过ROW_NUMBER()函数,给同一ID下的每条记录分配一个递增的序号,让后续Pivot能精准对应到每一列:
SELECT Id, Value, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Value) AS rn FROM car_owners;
执行后会得到带序号的中间结果:
--------------------- | Id | Value | rn | --------------------- | 1 | BMW | 1 | | 1 | Lada | 2 | | 1 | Skoda | 3 | | 2 | Audi | 1 | | 2 | Fiat | 2 | ---------------------
步骤2:用Pivot转成单行多列
基于上面的子查询,使用PIVOT函数将序号对应的Value转成不同列,同时用NVL()处理空值:
SELECT Id, NVL(Column1, '(empty)') AS Column1, NVL(Column2, '(empty)') AS Column2, NVL(Column3, '(empty)') AS Column3 FROM ( SELECT Id, Value, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Value) AS rn FROM car_owners ) PIVOT ( MAX(Value) FOR rn IN (1 AS Column1, 2 AS Column2, 3 AS Column3) );
执行后就能得到你期望的结果:
--------------------------------------- | Id | Column1 | Column2 | Column3 | --------------------------------------- | 1 | BMW | Lada | Skoda | | 2 | Audi | Fiat | (empty) | ---------------------------------------
补充说明
- 这里用
MAX()聚合函数是因为同一ID+序号的组合只有唯一值,聚合后不会改变结果,用MIN()也可以。 - 如果不确定每个ID最多有多少个车辆,静态SQL需要提前指定最大列数;如果需要动态适配列数,可以用动态SQL生成Pivot语句。
内容的提问来源于stack exchange,提问作者Beep
相关产品推荐
相关产品推荐

