PostgreSQL: 如何连接 Group By 结果集的行?

如何连接 “ group by” 结果集的行? 有点像行列转换,但又不完全是,描述颇为费劲,举例如下:

假如一张表有以下数据:

中国 台北
中国 香港
中国 上海
日本 东京
日本 大阪

要求得到如下结果集:

中国 台北,香港,上海
日本 东京,大阪

此文介绍几种实现以上要求的方法: PostgreSQL 版本为 9.0

创建初始表并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
skytf=> create table city (country character varying(64),city character varying(64));  
CREATE TABLE
skytf=> insert into city values ('中国','台北');
INSERT 0 1
skytf=> insert into city values ('中国','香港');
INSERT 0 1
skytf=> insert into city values ('中国','上海');
INSERT 0 1
skytf=> insert into city values ('日本','东京');
INSERT 0 1
skytf=> insert into city values ('日本','大阪');
INSERT 0 1

skytf=> select * From city;
country | city
---------+------
中国 | 台北
中国 | 香港
中国 | 上海
日本 | 东京
日本 | 大阪
(5 rows)

方法一: 使用聚集函数 array_agg

1.1 函数说明

Function name array_agg
Argument Type(s) any
Return Type array of the argument type
Description input values, including nulls, concatenated into an array

1.2 测试函数

1
2
3
4
5
6
7
8
9
10
11
12
13
skytf=> /df array_agg  
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+-----------+------------------+---------------------+------
pg_catalog | array_agg | anyarray | anyelement | agg
(1 row)

skytf=> select country,array_agg(city) from city group by country;
country | array_agg
---------+------------------
中国 | {台北,香港,上海}
日本 | {东京,大阪}
(2 rows)

备注: 这正是我们需要的结果,返回的结果类型为数组。

方法二: 使用聚集函数 string_agg

2.1函数说明

Function name string_agg(expression, delimiter)
Argument Type(s) text, text
Return Type text
Description input values concatenated into a string, separated by delimiter

2.2 测试函数

1
2
3
4
5
6
7
8
9
10
11
skytf=> select country,string_agg(city,',') from city group by country;  
country | string_agg
---------+----------------
中国 | 台北,香港,上海
日本 | 东京,大阪
(2 rows)
skytf=> select country,string_agg(city,',') from city where country='中国' group by country;
country | string_agg
---------+----------------
中国 | 台北,香港,上海
(1 row)

备注;string_agg 函数返回结果为 text 类型。

方法三: 自定义聚集函数

3.1 创建聚集函数

1
2
3
4
5
6
skytf=> CREATE AGGREGATE array_accum(anyelement) (  
skytf(> SFUNC = array_append,
skytf(> STYPE = anyarray,
skytf(> INITCOND = '{}'
skytf(> );
CREATE AGGREGATE

3.2 测试函数

1
2
3
4
5
skytf=> select country,array_accum(city) from city where country='中国' group by country;  
country | array_accum
---------+------------------
中国 | {台北,香港,上海}
(1 row)

备注:同样得到了预期的结果,返回的类型为数组。

参考

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/tech/database/237903.html

(0)
上一篇 2022年1月29日 22:30
下一篇 2022年1月29日 22:30

相关推荐

发表回复

登录后才能评论