oracle函数listagg使用
oracle函数listagg使用
作用
可以实现将多列记录聚合为一列记录,实现数据的压缩
语法结构
listagg(measure_expr,delimiter) within group ( order by order_by_clause);
解释:measure_expr可以是基于任何列的表达式
delimiter分隔符,默认为NULL
order_by_clause决定了列值的拼接顺序
获取某列并以逗号分隔:
--listagg
C##SCOTT@LHRCDB> select listagg(ename,',') from emp;
LISTAGG(ENAME,',')
----------------------------------------------------------------------------------------------------
SMITH,ALLEN,WARD,JONES,MARTIN,BLAKE,CLARK,SCOTT,KING,TURNER,ADAMS,JAMES,FORD,MILLER
C##SCOTT@LHRCDB>
--string_agg
qbadmin@10.14.41.157:20158/wind> select string_agg(ename,',') from emp;
string_agg
---------------------------------------------------------------------------
SMITH,ALLEN,WARD,JONES,MARTIN,BLAKE,CLARK,KING,TURNER,JAMES,FORD,MILLER
(1 row)
Time: 4ms total (execution 4ms / network 0ms)
qbadmin@10.14.41.157:20158/wind>
--group_concat
mysql> select * from t1;
+------+------+
| c1 | c2 |
+------+------+
| 1 | a |
| 2 | abc |
+------+------+
2 rows in set (0.00 sec)
mysql> select group_concat(c2) from t1;
+------------------+
| group_concat(c2) |
+------------------+
| a,abc |
+------------------+
1 row in set (0.00 sec)
mysql>
举例
普通函数,对工资进行排序,并按照逗号进行拼接
--listagg
C##SCOTT@LHRCDB> select deptno,listagg(ename,',')within group(order by sal)name from emp group by deptno;
DEPTNO NAME
---------- --------------------------------------------------
10 MILLER,CLARK,KING
20 SMITH,ADAMS,JONES,FORD,SCOTT
30 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
C##SCOTT@LHRCDB>
--string_agg
wind=# select deptno,string_agg(ename,',' order by sal) from emp group by deptno;
deptno | string_agg
--------+--------------------------------------
10 | MILLER,CLARK,KING
20 | SMITH,ADAMS,JONES,SCOTT,FORD
30 | JAMES,WARD,MARTIN,TURNER,ALLEN,BLAKE
(3 rows)
wind=#
--group_concat
mysql> select deptno,group_concat(ename order by sal SEPARATOR ',') from emp group by deptno;
+--------+-------------------------------------------------+
| deptno | group_concat(ename order by sal SEPARATOR ',') |
+--------+-------------------------------------------------+
| 10 | MILLER,CLARK,KING |
| 20 | SMITH,ADAMS,JONES,FORD,SCOTT |
| 30 | JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE |
+--------+-------------------------------------------------+
3 rows in set (0.00 sec)
mysql>
--listagg
C##SCOTT@LHRCDB> select deptno,ename,sal,listagg(ename,',')within group(order by sal)over(partition by deptno)name from emp;
DEPTNO ENAME SAL NAME
---------- ---------- ---------- --------------------------------------------------
10 MILLER 1300 MILLER,CLARK,KING
10 CLARK 2450 MILLER,CLARK,KING
10 KING 5000 MILLER,CLARK,KING
20 SMITH 800 SMITH,ADAMS,JONES,SCOTT,FORD
20 ADAMS 1100 SMITH,ADAMS,JONES,SCOTT,FORD
20 JONES 2975 SMITH,ADAMS,JONES,SCOTT,FORD
20 SCOTT 3000 SMITH,ADAMS,JONES,SCOTT,FORD
20 FORD 3000 SMITH,ADAMS,JONES,SCOTT,FORD
30 JAMES 950 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
30 MARTIN 1250 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
30 WARD 1250 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
30 TURNER 1500 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
30 ALLEN 1600 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
30 BLAKE 2850 JAMES,MARTIN,WARD,TURNER,ALLEN,BLAKE
已选择 14 行。
C##SCOTT@LHRCDB>