行列转换之字符串拼接(二)、LISTAGG函数

本文介绍 Oracle 11g R2 中引入的 LISTAGG 函数,一种强大的字符串聚合工具。通过示例展示了如何使用该函数按时间顺序拼接字符串,并对比 WM_CONCAT 函数,总结了 LISTAGG 的特点和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串拼接(String Aggregation Techniques)是数据处理时经常需要用到一个技术,比如需要按时间顺序拼装一个快递的运输记录,或者将流程中各个环节的处理人拼装为一个字符串。

Oracle中有多种方法来实现这个功能,这里罗列几种,详细用法可以参考下面的文章:
- WM_CONCAT函数
- LISTAGG函数
- 自定义聚合函数

本文介绍第二种:LISTAGG函数,这是Oracle11gR2开始正式推出的字符串聚合函数,功能非常强大。

0.测试样例及基本用法

从all_objects视图中取4个表记录和3个视图记录作为测试数据:

SQL> CREATE TABLE T_STRAGG AS
  2    select OBJECT_TYPE,CREATED,OBJECT_NAME from ALL_OBJECTS WHERE OBJECT_TYPE='TABLE' AND rownum<5
  3    UNION ALL
  4    select OBJECT_TYPE,CREATED,OBJECT_NAME from ALL_OBJECTS WHERE OBJECT_TYPE='VIEW' AND rownum<4;
Table created

SQL> select OBJECT_TYPE,TO_CHAR(CREATED,'YYYY-MM-DD HH24:MI:SS') CREATED,OBJECT_NAME from T_STRAGG;
OBJECT_TYPE         CREATED             OBJECT_NAME
------------------- ------------------- ------------------------------
TABLE               2013-10-09 18:23:43 DUAL
TABLE               2013-10-09 18:23:44 SYSTEM_PRIVILEGE_MAP
TABLE               2013-10-09 18:23:45 TABLE_PRIVILEGE_MAP
TABLE               2013-10-09 18:23:47 STMT_AUDIT_OPTION_MAP
VIEW                2013-10-09 18:23:53 ALL_XML_SCHEMAS
VIEW                2013-10-09 18:23:56 ALL_XML_SCHEMAS2
VIEW                2013-10-09 18:23:54 V_$ADVISOR_CURRENT_SQLPLAN

现在想要根据OBJECT_TYPE分组,将OBJECT_NAME按时间顺序拼装成类似物流信息的字符串:

2013-10-09 18:23:43@DUAL
2013-10-09 18:23:44@SYSTEM_PRIVILEGE_MAP
2013-10-09 18:23:45@TABLE_PRIVILEGE_MAP

实现方法很简单:

SQL> select object_type
  2        ,LISTAGG(TO_CHAR(CREATED,'YYYY-MM-DD HH24:MI:SS')||'@'||OBJECT_NAME,CHR(10)) WITHIN GROUP(ORDER BY CREATED) AS TXT
  3    FROM T_STRAGG
  4    GROUP BY object_type;
OBJECT_TYPE         TXT
------------------- --------------------------------------------------------------------------------
TABLE               2013-10-09 18:23:43@DUAL
                    2013-10-09 18:23:44@SYSTEM_PRIVILEGE_MAP
                    2013-10-09 18:23:45@TABLE_PRIVILEGE_MAP
                    2013-10-09 18:23:47@STMT_AUDIT_OPTION_MAP
VIEW                2013-10-09 18:23:53@ALL_XML_SCHEMAS
                    2013-10-09 18:23:54@V_$ADVISOR_CURRENT_SQLPLAN
                    2013-10-09 18:23:56@ALL_XML_SCHEMAS2

跟WM_CONCAT相比,LISTAGG有如下特征(优缺点):

1.返回值的分隔符可以自定义

这一点大大方便了开发人员,只要有需要可以摆出各种姿势^_^

2.返回值类型是VARCHAR2

跟WM_CONCAT相反,速度是快了,但如果数据量大就报错
ORA-01489: result of string concatenation is too long
(字符串连接的结果过长)

SQL> INSERT INTO T_STRAGG select object_type,CREATED,OBJECT_NAME FROM ALL_OBJECTS where rownum<1000;
999 rows inserted

SQL> select object_type
  2        ,LISTAGG(TO_CHAR(CREATED,'YYYY-MM-DD HH24:MI:SS')||'@'||OBJECT_NAME,CHR(10)) WITHIN GROUP(ORDER BY CREATED) AS TXT
  3    FROM T_STRAGG
  4    GROUP BY object_type;

ORA-01489: result of string concatenation is too long

没办法,用回WM_CONCAT?
还是建议用第三个方法:自定义聚合函数

3.不支持DISTINCT

直接报错ORA-30482: DISTINCT option not allowed for this function
(DISTINCT 选项在此函数中禁用)

SQL> select object_type,LISTAGG(DISTINCT OBJECT_NAME) WITHIN GROUP(ORDER BY CREATED) AS TXT
  2    FROM T_STRAGG
  3    GROUP BY object_type;

ORA-30482: DISTINCT option not allowed for this function

解决方法:
1.先distinct,结果再listagg
2.自定义聚合函数来取代listagg函数

结论

  1. listagg能满足的情况下,用listagg,不要用wm_concat
  2. listagg无法满足的情况下,还是网上拿一个自定义聚合函数好了
### Oracle 数据库字符串拼接函数 `CONCAT` 和 `||` #### 函数描述 在 Oracle 数据库中,提供了多种方式来实现字符串拼接操作。其中最常见的两种方法分别是使用内置函数 `CONCAT` 和运算符 `||`。 1. **`CONCAT` 函数** - `CONCAT` 是一个专门用于字符串拼接的 SQL 函数,在 Oracle 中定义为 `CONCAT(char1, char2)`[^1]。 - 它仅支持两个参数作为输入,并返回这两个参数按顺序连接后的结果。 ```sql SELECT CONCAT('你', '好') FROM DUAL; -- 返回:你好 ``` - 如果需要连接超过两个字符串,则可以通过嵌套调用的方式完成: ```sql SELECT CONCAT(CONCAT('aa', 'bb'), 'cc') FROM DUAL; -- 返回:aabbcc ``` 2. **`||` 运算符** - `||` 是一种更灵活的字符串拼接工具,可以直接用于 SQL 查询语句中[^4]。 - 支持任意数量的字符串或列名之间的连续拼接,语法更加简洁直观。 ```sql SELECT '你' || '好' || '吗' FROM DUAL; -- 返回:你好吗 ``` - 同样适用于表字段间的拼接操作: ```sql SELECT Name || '-' || Languages FROM GradesTable WHERE Name = '李明'; -- 假设 GradesTable 表存在记录 {Name: 李明, Languages: 88},则返回:李明-88 ``` #### 性能对比与注意事项 尽管两者都能满足基本的字符串拼接需求,但在实际开发过程中需注意以下几点: - 当涉及大量复杂的数据处理时,建议优先选用 `||` 运算符,因其具有更高的灵活性和可读性[^5]。 - 对于简单的两字符串组合场景下,`CONCAT` 的表现同样高效,但由于其严格的双参限制可能增加额外编码负担。 - 特殊情况下如需聚合多行数据成单一字符串形式,应考虑采用其他专用功能比如 LISTAGG()[^3] 而非单纯依赖基础级联手段。 ```sql -- 利用 LISTAGG 实现跨行汇总示例 SELECT LISTAGG(Name, ', ') WITHIN GROUP (ORDER BY Name) AS NamesList FROM GradesTable; ``` 以上即是对 Oracle 数据库内字符串拼接机制较为全面的解析介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值