简体   繁体   English

如何展平 SQL 查询的结果 - 将行转置为列?

[英]How Can I Flatten the Results of a SQL Query - Transposing Rows to Columns?

I have a table that I want to join some other tables on to.我有一张桌子,我想加入其他一些桌子。 The table called "OfficePers" has a field for the Office Location ID as well as a field for the IDs of people who work in that location and another field with their names.名为“OfficePers”的表有一个字段表示办公室位置 ID,还有一个字段表示在该位置工作的人员的 ID,另一个字段表示他们的姓名。 For example, the table is of the following format:例如,该表的格式如下:

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

What I want to do is create a subquery that returns one result per office location and creates aliases for each personID and name - so the above table would be transformed into something like the following:我想要做的是创建一个子查询,它为每个办公室位置返回一个结果,并为每个 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     |           |           |           |

 

I was thinking of perhaps doing something like just joining the "OfficePers" table on itself multiple times but I'm not sure what function I could use to parse out each Person ID - I'm familiar with using Max and Min but that wouldn't work with a case of having more than 2 Person IDs at the same location.我正在考虑做一些事情,比如多次加入“OfficePers”表,但我不确定我可以用什么 function 来解析每个人 ID - 我熟悉使用 Max 和 Min 但这不会t 适用于在同一位置具有 2 个以上人员 ID 的情况。

The simplest method is to combine these into a single column using listagg() :最简单的方法是使用listagg()将它们组合成一个列:

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

I do not recommend putting the values in separate columns for several reasons.出于多种原因,我不建议将值放在单独的列中。 First, you don't know how many columns you will need.首先,您不知道需要多少列。 Second, you can do this using dynamic SQL, but you cannot create a view for the result.其次,您可以使用动态 SQL 执行此操作,但您无法为结果创建视图。 Third, the same person could -- in theory -- appear in multiple rows, but the person would likely be in different columns.第三,理论上,同一个人可能出现在多行中,但该人可能会出现在不同的列中。

EDIT:编辑:

If you want exactly six columns, you can use conditional aggregation:如果你想要六列,你可以使用条件聚合:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM