sql - 如何展平 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 的情况。
解决方案
最简单的方法是使用以下方法将它们组合成一列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;
推荐阅读
- spring - Spring RestTemplate 消息转换器读取/使用多部分/混合响应
- python - 为什么我不能使用 Selenium 在 Python 中将_keys 发送到 Twitch 搜索栏?
- php - Yii2 - radioList 选择绑定到两个不同的字段
- http - Flutter http获得完成率?
- angular - 如何检查元素是否是模板Angular中的HTMLElement?
- regex - 使用 Notepad++ 正则表达式将日期格式 2007-10-26T06:36:28 替换为标准 YYYY-MM-DD
- python-3.x - 如何通过单元测试测试其他功能?
- organization - 作为开发人员,如何组织你学到的东西?
- java - 在 Spring 和 Angular 应用程序中更改 JSON 结构的位置和方式
- python - 如何删除所有表,包括依赖对象