欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用PostgreSQL的listagg函数进行分组排序聚合操作,并且了解string_agg的兼容用法。包括行列转换和CSV构造等技巧。

最编程 2024-08-08 12:24:14
...

string_agg 代替listagg,实现同样功能。

建表

postgres=# create table tbl1 (gid int, val text, ts timestamp default clock_timestamp());  
CREATE TABLE  

写入测试数据

postgres=# insert into tbl1 values (1,'a'),(1,'b'),(1,null),(2,'test'),(2,'a""b"c'),(3,'fw');  
INSERT 0 6  

数据

postgres=# select * from tbl1;  
 gid |  val   |             ts               
-----+--------+----------------------------  
   1 | a      | 2018-10-29 21:00:24.593859  
   1 | b      | 2018-10-29 21:00:24.593994  
   1 |        | 2018-10-29 21:00:24.593997  
   2 | test   | 2018-10-29 21:00:24.593998  
   2 | a""b"c | 2018-10-29 21:00:24.594  
   3 | fw     | 2018-10-29 21:00:24.594001  
(6 rows)  

逆向聚合,双引号作为quote字符,转义文本内的双引号,空值使用NULL表示。

postgres=# select gid, string_agg(coalesce('"'||replace(val,'"','\"')||'"','NULL'),',' order by ts desc) from tbl1 group by gid;  
 gid |     string_agg       
-----+--------------------  
   1 | NULL,"b","a"  
   2 | "a\"\"b\"c","test"  
   3 | "fw"  
(3 rows)  

正向聚合,双引号作为quote字符,转义文本内的双引号,空值使用NULL表示。

postgres=# select gid, string_agg(coalesce('"'||replace(val,'"','\"')||'"','NULL'),',' order by ts) from tbl1 group by gid;  
 gid |     string_agg       
-----+--------------------  
   1 | "a","b",NULL  
   2 | "test","a\"\"b\"c"  
   3 | "fw"  
(3 rows)  

正向聚合,不使用QUOTE,直接去除NULL值

postgres=# select gid, string_agg(val,',' order by ts) from tbl1 group by gid;  
 gid | string_agg    
-----+-------------  
   1 | a,b  
   2 | test,a""b"c  
   3 | fw  
(3 rows)  

order by 任意字段、表达式、转换

order by可以任意字段、表达式、类型转换

select gid, string_agg(val,',' order by xx::numeric) from tbl1 group by gid;

select gid, string_agg(val,',' order by abs(xxx)) from tbl1 group by gid;

select gid, string_agg(val,',' order by mod(x,5),xxxx) from tbl1 group by gid;
postgres=# create table tbl(id int, c1 text);
CREATE TABLE
postgres=# insert into tbl values (1,'1'),(2,'12'),(3,'2');
INSERT 0 3

postgres=# select string_agg(c1,',' order by c1::numeric) from tbl;
 string_agg 
------------
 1,2,12
(1 row)

postgres=# select string_agg(c1,',' order by c1) from tbl;
 string_agg 
------------
 1,12,2
(1 row)