oracle 10g怎么实现 listagg功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 10g怎么实现 listagg功能相关的知识,希望对你有一定的参考价值。

用wn_concat() 函数

1、把以下图中Name一样的数据合并为一条,而且NO的值要这样显示如 C.1,C.2

2、实现这种效果的操作如下,先把Name的值进行分组(group by),再把NO的值用 wm_concat()函数合并起来(注意:记得要to_char(),要不然数据显示不出来)

参考技术A

oracle 10g 实现listagg功能:

listagg函数的语法结构如下:
LISTAGG( [,]) WITHIN GROUP (ORDER BY ) [OVER (PARTITION BY )]
listagg虽然是聚合函数,但可以提供分析功能(比如可选的OVER()子句)。使用listagg中,下列中的元素是必须的:
需要聚合的列或者表达式。
WITH GROUP 关键词。
分组中的ORDER BY子句。
下面将演示listagg函数使用的例子。
listagg 作为聚合函数。

参考技术B oracle 本身有个函数是wmsys.wm_concat(),这个函数可以实现listagg的部分功能。不过,10g的这个函数返回是varchar2(4000),11g的时候是blob。 参考技术C listagg 语法概述

listagg函数的语法结构如下:
LISTAGG( [,]) WITHIN GROUP (ORDER BY ) [OVER (PARTITION BY )]
listagg虽然是聚合函数,但可以提供分析功能(比如可选的OVER()子句)。使用listagg中,下列中的元素是必须的:
需要聚合的列或者表达式
WITH GROUP 关键词
分组中的ORDER BY子句
下面将演示listagg函数使用的例子
listagg 作为聚合函数

下面以EMP表为例,按照部门分组聚合employee name,并以,为分隔符。
SQL> SELECT deptno 2 , LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees 3 FROM emp 4 GROUP BY 5 deptno;
DEPTNO EMPLOYEES ---------- ------------------------------------------------------------ 10 CLARK,KING,MILLER 20 ADAMS,FORD,JONES,SCOTT,SMITH 30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD 3 rows selected.

注:在每个聚合元素中,本例选用empolyee name字段进行排序,不过需要说明的是,在其它实现字符串聚合方法中,排序可是重量级的任务。
下面的例子中,empolyee name的聚合将按照hire date来排序。
SQL> SELECT deptno
2 , LISTAGG(ename, ',') WITHIN GROUP (ORDER BY hiredate) AS employees
3 FROM emp
4 GROUP BY
5 deptno;

DEPTNO EMPLOYEES ---------- ------------------------------------------------------------ 10 CLARK,KING,MILLER 20 SMITH,JONES,FORD,SCOTT,ADAMS 30 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 3 rows selected.
可以看到,每组中empolyee names的排序与前面的例子截然不同。
listagg作为分析函数

与许多的聚合函数类似,listagg通过加上over()子句可以实现分析功能,下面的例子将展示分析功能:SQL> SELECT deptno 2 , ename 3 , hiredate 4 , LISTAGG(ename, ',') 5 WITHIN GROUP (ORDER BY hiredate) 6 OVER (PARTITION BY deptno) AS employees 7 FROM emp; DEPTNO ENAME HIREDATE EMPLOYEES ---------- ---------- ----------- ------------------------------------- 10 CLARK 09/06/1981 CLARK,KING,MILLER 10 KING 17/11/1981 CLARK,KING,MILLER 10 MILLER 23/01/1982 CLARK,KING,MILLER 20 SMITH 17/12/1980 SMITH,JONES,FORD,SCOTT,ADAMS 20 JONES 02/04/1981 SMITH,JONES,FORD,SCOTT,ADAMS 20 FORD 03/12/1981 SMITH,JONES,FORD,SCOTT,ADAMS 20 SCOTT 19/04/1987 SMITH,JONES,FORD,SCOTT,ADAMS 20 ADAMS 23/05/1987 SMITH,JONES,FORD,SCOTT,ADAMS 30 ALLEN 20/02/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 30 WARD 22/02/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 30 BLAKE 01/05/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 30 TURNER 08/09/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 30 MARTIN 28/09/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 30 JAMES 03/12/1981 ALLEN,WARD,BLAKE,TURNER,MARTIN,JAMES 14 rows selected. 切记:分析函数不会丢失结果集的每一行,而字符串的聚合却并非如此

MySQL 中的聚合函数 - 列表(如 Oracle 中的 LISTAGG)

【中文标题】MySQL 中的聚合函数 - 列表(如 Oracle 中的 LISTAGG)【英文标题】:Aggregate function in MySQL - list (like LISTAGG in Oracle) 【发布时间】:2012-03-16 09:59:06 【问题描述】:

我需要一个函数,它返回字符串列表。

我在表中有这样的数据:

Id    MyString
------------------------
 1    First
 2    Second
 3    Third
 4    Fourth

我需要这样的功能(这样的东西在 oracle 中有效):

select LISTAGG(MyString, ', ') as myList where id < 4

返回如下内容:

myList
------------------------
First, Second, Third

有什么想法吗?

【问题讨论】:

那是GROUP_CONCAT() in MySQL。 MySQL Results as comma separated list的可能重复 【参考方案1】:

您正在寻找GROUP_CONCAT()

试试这个:

select group_concat(MyString separator ', ') as myList from table
where id < 4

当然,你可以group by结果。

【讨论】:

group_concat 在字符串的开头包含一个分隔符,任何不同于空的内容。知道为什么吗?【参考方案2】:

从 MySQL 5.7.22 开始,您还可以使用两个 JSON 聚合函数:JSON_ARRAYAGG 或 JSON_OBJECTAGG。您可以将这些与MySQL's JSON functions 组合在一起,以获取汇总为 JSON 的结果。与GROUP_CONCAT 不同,除了max_allowed_packet(影响所有查询)之外,没有任何MySQL 配置参数会限制返回值的大小。

【讨论】:

以上是关于oracle 10g怎么实现 listagg功能的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 10g 中的 LISTAGG 替代方案

LISTAGG 相当于 10 克 [重复]

用listagg怎么替代这个写法

oracle中sql语句的问题

SQL语句实现行转列

oracle listagg的 截取长度限制有没有啥方法解决