Oracle字符串聚合函数LISTAGG

在Oracle 19c中,LISTAGG函数是一个非常有用的字符串聚合函数,它可以将来自多个行的值连接成一个单独的字符串。这个函数特别适用于将分组内的多个值合并为一个逗号分隔(或其他分隔符)的字符串。

LISTAGG函数的基本语法如下:

LISTAGG(column, [delimiter]) WITHIN GROUP (ORDER BY order_by_clause) [OVER(PARTITION BY paration_by_clause) ]
  • column 是你想要聚合的列。
  • [delimiter] 是可选的,用于指定值之间的分隔符,默认为NULL。如果不指定分隔符,则所有值将直接连接在一起,没有分隔。
  • WITHIN GROUP (ORDER BY order_by_clause) 是必须的,用于指定聚合时值的排序方式。
  • OVER(PARTITION BY XXX) 在不使用GROUP BY语句时候,也可以使用LISTAGG函数

示例1

假设我们有一个名为employees的表,其中包含department_idemployee_name两个字段,我们想要为每个部门列出所有员工的名字,名字之间用逗号分隔。

SELECT
    department_id,
    LISTAGG(employee_name, ', ') WITHIN GROUP (ORDER BY employee_name) AS employees
FROM
    employees
GROUP BY
    department_id;

这个查询将返回每个部门的ID和该部门所有员工名字的列表,名字之间用逗号加空格分隔。

示例2

SYS@orcl> create table t_listagg(id number,nation varchar2(32),city varchar2(128),constraint pk_t_listagg_id primary key(id));

Table created.

INSERT INTO t_listagg
select 1 ID,'China' nation ,'广州' city from dual union all 
select 2 ID,'China' nation ,'深圳' city from dual union all  
select 3 ID,'China' nation ,'上海' city from dual union all  
select 4 ID,'China' nation ,'北京' city from dual union all  
select 5 ID,'USA' nation ,'New York' city from dual union all  
select 6 ID,'USA' nation ,'Boston' city from dual union all  
select 7 ID,'Japan' nation ,'Tokyo' city from dual  
COMMIT;

SYS@orcl> col city format a30
SYS@orcl> select * from t_listagg;

        ID NATION                           CITY
---------- -------------------------------- ------------------------------
         1 China                            广州
         2 China                            深圳
         3 China                            上海
         4 China                            北京
         5 USA                              New York
         6 USA                              Boston
         7 Japan                            Tokyo

SYS@orcl> col LISTAGG_CITY format a60
SYS@orcl> set linesize 200
-- 用于指定聚合时值的,以city升序方式排序
SYS@orcl> select nation,listagg(city,',') within GROUP (order by city) listagg_city  FROM t_listagg  GROUP by nation;

NATION                           LISTAGG_CITY
-------------------------------- ------------------------------------------------------------
China                            上海,北京,广州,深圳
Japan                            Tokyo
USA                              Boston,New York
-- 用于指定聚合时值的,以ID倒序方式排序
SYS@orcl> select nation,listagg(city,',') within GROUP (order by ID desc) listagg_city  FROM t_listagg  GROUP by nation;

NATION                           LISTAGG_CITY
-------------------------------- ------------------------------------------------------------
China                            北京,上海,深圳,广州
Japan                            Tokyo
USA                              Boston,New York

-- 用于指定聚合时值的,以ID倒序方式排序,以nation分组
SYS@orcl> select id,nation,city,listagg(city,',') within GROUP (order by id desc)  over (partition by nation) rank  FROM t_listagg;

        ID NATION                           CITY                           RANK
---------- -------------------------------- ------------------------------ ------------------------------------------------------------
         4 China                            北京                           北京,上海,深圳,广州
         3 China                            上海                           北京,上海,深圳,广州
         2 China                            深圳                           北京,上海,深圳,广州
         1 China                            广州                           北京,上海,深圳,广州
         7 Japan                            Tokyo                          Tokyo
         6 USA                              Boston                         Boston,New York
         5 USA                              New York                       Boston,New York

7 rows selected.

注意事项

  1. 字符串长度限制LISTAGG函数在Oracle中有字符串长度的限制。在Oracle 12c及之前的版本中,这个限制是4000字节。从Oracle 12c Release 2开始,可以通过设置ON OVERFLOW TRUNCATE子句来处理超出长度的情况,但Oracle 19c仍然默认有这个限制。如果聚合的字符串超过了这个长度,查询将失败。

  2. 处理超长字符串:如果你预期聚合的字符串可能会超过4000字节的限制,你可以考虑使用XMLAGGXMLELEMENT函数作为替代方案,因为XMLAGG不受此限制。但是,请注意,使用XMLAGG会使查询更加复杂,并且可能需要额外的处理来将XML类型的结果转换为字符串。

  3. 性能:对于大型数据集,LISTAGG函数可能会影响查询性能。在可能的情况下,考虑使用索引、优化查询逻辑或考虑数据聚合的替代方法。

  4. 版本兼容性:虽然LISTAGG在Oracle 11g Release 2及更高版本中可用,但某些特性(如ON OVERFLOW TRUNCATE)可能在较新的版本中才可用。始终参考你正在使用的Oracle版本的官方文档。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle中的LISTAGG函数是一个字符串聚合函数,它将一组行的列值组合成单个字符串,这些值可以通过逗号、空格或其他指定的分隔符分隔。这个函数非常适合将多个行的数据合并成一个字段的格式,用于报表或导出数据时非常有用。 LISTAGG函数的基本语法如下: ```sql LISTAGG(字段名, 分隔符) WITHIN GROUP (ORDER BY 排序字段名 [ASC|DESC]) ``` - `字段名` 是你想要聚合成字符串的列名。 - `分隔符` 是用来分隔各个值的字符或字符串。 - `ORDER BY 排序字段名` 指定了合并值之前需要排序的列名。可以使用 `ASC` 或 `DESC` 来指定升序或降序排序。 - `WITHIN GROUP` 是聚合函数的一个子句,用于定义排序的顺序。 下面是一个简单的例子: ```sql SELECT employee_id, LISTAGG(last_name, ', ') WITHIN GROUP (ORDER BY last_name) AS last_name_list FROM employees GROUP BY employee_id; ``` 在这个例子中,我们对 `employees` 表中的 `employee_id` 进行分组,并将每个组内的 `last_name` 按字母顺序排序后,使用逗号加空格作为分隔符合并成一个字符串,然后将这个字符串命名为 `last_name_list`。 使用LISTAGG函数时要注意的一点是,如果所有行转换成一个字符串后超过了Oracle字符串限制长度,你将收到一个错误。Oracle中的最大字符串长度通常是4000字节,但可以通过设置初始化参数 `MAX_STRING_SIZE` 为 `EXTENDED` 来使用更长的字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值