Oracle字符串行专列(字符串聚合技术)(一)

2015-01-22 21:09:46 · 作者: · 浏览: 12
 
 
 


1 String Aggregation Techniques 字符串聚合技术

On occasion it is necessary to aggregate data from a number ofrows into a single row, giving a list of data associated with a specific value.Using the SCOTT.EMP table as an example, we might want to retrieve a list ofemployees for each department. Below is a list of the base data and the type ofoutput we would like to return from an aggregate query.
偶尔我们需要将多行数据聚合成一行,给出指定数据值列表。下面我们以EMP表为例,我们希望按照部门聚合其下面的所有员工。
Base Data:
    DEPTNO ENAME
---------- ----------
        20 SMITH
        30 ALLEN
        30 WARD
        20 JONES
        30 MARTIN
        30 BLAKE
        10 CLARK
        20 SCOTT
        10 KING
        30 TURNER
        20 ADAMS
        30 JAMES
        20 FORD
        10 MILLER
Desired Output:
    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 SMITH,FORD,ADAMS,SCOTT,JONES
        30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD
This article is based on a thread from asktom.oracle.com and contains several methods toachieve the desired results.
我们将采用以下方法:
LISTAGG Analytic Function in 11g Release 2 WM_CONCAT Built-in Function (Not Supported) User-Defined Aggregate Function Specific Function Generic Function using Ref Cursor ROW_NUMBER() and SYS_CONNECT_BY_PATH functions in Oracle 9i COLLECT function in Oracle 10g

1.1 LISTAGG AnalysticFunction in 11g Release 2

The LISTAGG analyticfunction was introduced in Oracle 11g Release 2, making it very easy toaggregate strings. The nice thing about this function is it also allows us toorder the elements in the concatenated list. If you are using 11g Release 2 youshould use this function for string aggregation.

LISTAGG函数由11gr2引入,使得字符串聚合操作更加容易。并且允许我们制定排序规则。

COLUMN employees FORMAT A50
 
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM   emp
GROUP BY deptno;
 
    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
 
3 rows selected.

1.2 WM_CONCAT Built-inFunction (Not Supported)

If you are not running 11g Release 2, but are running a version ofthe database where the WM_CONCAT functionis present, then it is a zero effort solution as it performs the aggregationfor you. It is actually an example of a user defined aggregate functiondescribed below, but Oracle have done all the work for you.

如果我们使用的是11g r2之前版本,那么可以选择使用WM_CONCAT内置函数。

COLUMN employees FORMAT A50
 
SELECT deptno, wm_concat(ename) AS employees
FROM   emp
GROUP BY deptno;
 
    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 SMITH,FORD,ADAMS,SCOTT,JONES
        30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD
 
3 rows selected.

Note. WM_CONCAT isan undocumented function and as such is not supported by Oracle for userapplications (MOS Note ID 1336219.1). If this concerns you,use a User-Defined Aggregate Function described below.

不过注意WM_CONCAT属于非文档型函数并且使用该函数的应用程序将不被ORACLE支持(出了事Oracle不负任何责任)。如果这一点困扰到你,那么可以选择下面的用户自定义聚合函数。

1.3 User-Defined AggregateFunction

The WM_CONCAT functiondescribed above is an example of a user-defined aggregate function that Oraclehave already created for you. If you don't want to use WM_CONCAT, you can create your ownuser-defined aggregate function as described at asktom.oracle.com.

CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
  g_