首页 > 解决方案 > 如何展平 SQL 查询的结果 - 将行转换为列?

问题描述

我有一张桌子,我想加入其他一些桌子。名为“OfficePers”的表有一个用于办公室位置 ID 的字段、一个用于在该位置工作的人员的 ID 的字段以及另一个带有他们姓名的字段。例如,该表的格式如下:

| OfficeLocation | PersonID |
|--------------  | -------- |    
|321             |   2323   |   
|321             |   2355   |   
|321             |   1234   |   
|321             |   7899   |   
|321             |   32091  |   
|321             |   777    |       
|1654            |   4232   |   
|121243          |   345    |       
|121243          |   343    |       
|121243          |   111    |   

我想要做的是创建一个子查询,它为每个办公室位置返回一个结果,并为每个 personID 和 name 创建别名 - 因此上表将转换为如下所示:

| OfficeLocation |  PersonID_1 | PersonID_2 | PersonID_3 | PersonID_4| PersonID_5| PersonID_6|
| -------------- | ----------- |----------- |----------- |-----------|-----------|-----------|
| 321            |      2323   |    2355    |   1234     |  7899     |  32091    |  777      |
| 1654           |      4232   |            |            |           |           |           |
| 121243         |       345   |    343     |    111     |           |           |           |

 

我正在考虑做一些事情,比如多次加入“OfficePers”表,但我不确定我可以使用什么函数来解析每个人 ID - 我熟悉使用 Max 和 Min,但那不会t 适用于在同一位置具有 2 个以上人员 ID 的情况。

标签: sqloraclepivot

解决方案


最简单的方法是使用以下方法将它们组合成一列listagg()

select OfficeLocation,
       listagg(personid, ',') within group (order by personid) as personids
from t
group by OfficeLocation;

出于多种原因,我不建议将值放在单独的列中。首先,您不知道需要多少列。其次,您可以使用动态 SQL 来执行此操作,但不能为结果创建视图。第三,理论上,同一个人可能出现在多行中,但该人可能会出现在不同的列中。

编辑:

如果你想要六列,你可以使用条件聚合:

select OfficeLocation,
       max(case when seqnum = 1 then PersonId) as PersonId_1,
       max(case when seqnum = 2 then PersonId) as PersonId_2,
       max(case when seqnum = 3 then PersonId) as PersonId_3,
       max(case when seqnum = 4 then PersonId) as PersonId_4,
       max(case when seqnum = 5 then PersonId) as PersonId_5,
       max(case when seqnum = 6 then PersonId) as PersonId_6
from (select t.*,
             row_number() over (partition by OfficeLocation order by personid) as seqnum
      from t
     ) t
group by OfficeLocation;

推荐阅读