我正在使用postgres 9.3.5。
鉴于以下数据:
select * from department;
id | name
----+-----------
1 | sales
2 | marketing
3 | HR
和
select * from people;
id | department_id | first_name | last_name
----+---------------+------------+-----------
1 | 1 | Tom | Jones
2 | 1 | Bill | Cosby
3 | 2 | Jessica | Biel
4 | 1 | Rachel | Hunter
5 | 2 | John | Barnes
我想返回这样的结果集:
id | name | first_name-1 | last_name-1 | first_name-2 | last_name-2 | first_name-3 | last_name-3
----+-----------+--------------+-------------+--------------+-------------+--------------+------------
1 | sales | Tom | Jones | Bill | Cosby | Rachel | Hunter
2 | marketing | Jessica | Biel | John | Barnes
3 | HR |
这可能吗?
Max Shawabkeh使用GROUP_CONCAT提供的答案here已关闭 - 但它不会作为数据集中的额外字段返回,而是将它们连接成一个字段。
答案 0 :(得分:1)
您需要交叉制表(有时称为 pivot )。
在你的情况下看起来像这样:
SELECT * FROM crosstab(
$$SELECT d.id, d.name,'p' AS dummy_cat
,concat_ws(' ', p.first_name, p.last_name) AS person
FROM department d
LEFT JOIN people p ON p.department_id = d.id
ORDER BY d.department_id, p.id$$
)
AS ct (id int, department text, person_1 text, person_2 text, person_3 text);
返回:
id department person_1 person_2 person_3
--------------------------------------------------------
1 sales Tom Jones Bill Cosby Rachel Hunter
2 marketing Jessica Biel John Barnes <NULL>
3 HR <NULL> <NULL> <NULL>
非常类似于此相关案例(对特殊困难的解释):
但是这种情况更简单:因为您似乎并不关心列出人员的顺序,您可以使用crosstab()
的基本单参数形式。
另外,根据您的评论,您希望所有部门,即使没有人员被分配。相应地调整了LEFT JOIN。
此相关答案的基本详情: