我收集到的oracle中的“行列转换”函数

1、第一种

first implementation simply uses static sql to select all of the values for B from
T for a given A and string them together:

函数代码:

CREATE OR REPLACE FUNCTION get_transposed (p_a IN VARCHAR2)
   RETURN VARCHAR2
IS
   l_str   VARCHAR2 (2000) DEFAULT NULL;
   l_sep   VARCHAR2 (1) DEFAULT NULL;
BEGIN
   FOR x IN (SELECT b
               FROM t
              WHERE a = p_a)
   LOOP
      l_str := l_str || l_sep || x.b;
      l_sep := '-';
   END LOOP;

   RETURN l_str;
END;
/

 

样例:

column t format a30;

drop table t;


create table t
( a varchar2(25),
  b varchar2(25)
);

insert into t values ( '210','5000' );
insert into t values ( '210','5001' );
insert into t values ( '210','5002' );
insert into t values ( '220','6001' );
insert into t values ( '220','6002' );
commit;


 

select a, get_transposed( a ) t
from t
group by a
/

A                         T
------------------------- ------------------------------
210                       5000-5001-5002
220                       6001-6002

 

2、第二种

next example is more complex.  We will pass in the name of the 'key' column (the
column to pivot on), a value for that column, the name of the column to actually select
out and string together and finally the table to select from:


函数代码:

create or replace
function transpose( p_key_name in varchar2,
                    p_key_val  in varchar2,
                    p_other_col_name in varchar2,
                    p_tname     in varchar2 )
return varchar2
as
    type rc is ref cursor;
    l_str    varchar2(4000);
    l_sep    varchar2(1);
    l_val    varchar2(4000);

    l_cur    rc;
begin

    open l_cur for 'select '||p_other_col_name||'
                      from '|| p_tname || '
                     where ' || p_key_name || ' = :x '
                using p_key_val;

    loop
        fetch l_cur into l_val;
        exit when l_cur%notfound;
        l_str := l_str || l_sep || l_val;
        l_sep := '-';
    end loop;
    close l_cur;

    return l_str;
end;
/


 使用样例:

REM List the values of "B" for a given value
REM of "A" in the table "T"

select a, transpose( 'a', a, 'b', 't' ) t
  from t
 group by a
/

A                         T
------------------------- ------------------------------
210                       5000-5001-5002
220                       6001-6002

 

3、第三种

直接使用wm_sys.wm_concat,它可以使用“,”来连接字符串

参考样例:http://blog.csdn.net/yy_mm_dd/article/details/3182953

SQL> create table idtable (id number,name varchar2(30));

Table created

SQL> insert into idtable values(10,'ab');

1 row inserted

SQL> insert into idtable values(10,'bc');

1 row inserted

SQL> insert into idtable values(10,'cd');

1 row inserted

SQL> insert into idtable values(20,'hi');

1 row inserted

SQL> insert into idtable values(20,'ij');

1 row inserted
SQL> insert into idtable values(20,'mn');

1 row inserted

SQL> select * from idtable;

        ID NAME
---------- ------------------------------
        10 ab
        10 bc
        10 cd
        20 hi
        20 ij
        20 mn

6 rows selected
SQL> select id,wmsys.wm_concat(name) name from idtable
  2  group by id;

        ID NAME
---------- --------------------------------------------------------------------------------
        10 ab,bc,cd
        20 hi,ij,mn

SQL> select id,wmsys.wm_concat(name) over (order by id) name from idtable;

        ID NAME
---------- --------------------------------------------------------------------------------
        10 ab,bc,cd
        10 ab,bc,cd
        10 ab,bc,cd
        20 ab,bc,cd,hi,ij,mn
        20 ab,bc,cd,hi,ij,mn
        20 ab,bc,cd,hi,ij,mn

6 rows selected

SQL> select id,wmsys.wm_concat(name) over (order by id,name) name from idtable;

        ID NAME
---------- --------------------------------------------------------------------------------
        10 ab
        10 ab,bc
        10 ab,bc,cd
        20 ab,bc,cd,hi
        20 ab,bc,cd,hi,ij
        20 ab,bc,cd,hi,ij,mn

6 rows selected

个人觉得这个用法比较有趣.

SQL> select id,wmsys.wm_concat(name) over (partition by id) name from idtable;

        ID NAME
---------- --------------------------------------------------------------------------------
        10 ab,bc,cd
        10 ab,bc,cd
        10 ab,bc,cd
        20 hi,ij,mn
        20 hi,ij,mn
        20 hi,ij,mn

6 rows selected

SQL> select id,wmsys.wm_concat(name) over (partition by id,name) name from idtable;

        ID NAME
---------- --------------------------------------------------------------------------------
        10 ab
        10 bc
        10 cd
        20 hi
        20 ij
        20 mn

6 rows selected

 

 

4、第四种

自定义一个方法,相当于是wm_concat的源码,能够修改满足个性化的要求。

代码:

CREATE OR REPLACE TYPE string_agg_type AS OBJECT
                  (
                     total VARCHAR2 (10000),
                     STATIC FUNCTION ODCIAggregateInitialize (
                        sctx IN OUT string_agg_type)
                        RETURN NUMBER,
                     MEMBER FUNCTION ODCIAggregateIterate (
                        self    IN OUT string_agg_type,
                        VALUE   IN     VARCHAR2)
                        RETURN NUMBER,
                     MEMBER FUNCTION ODCIAggregateTerminate (
                        self          IN     string_agg_type,
                        returnValue      OUT VARCHAR2,
                        flags         IN     NUMBER)
                        RETURN NUMBER,
                     MEMBER FUNCTION ODCIAggregateMerge (
                        self   IN OUT string_agg_type,
                        ctx2   IN     string_agg_type)
                        RETURN NUMBER);


CREATE OR REPLACE TYPE BODY string_agg_type
IS
   STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT string_agg_type)
      RETURN NUMBER
   IS
   BEGIN
      sctx := string_agg_type (NULL);
      RETURN ODCIConst.Success;
   END;

   MEMBER FUNCTION ODCIAggregateIterate (self    IN OUT string_agg_type,
                                         VALUE   IN     VARCHAR2)
      RETURN NUMBER
   IS
   BEGIN
      self.total := self.total || ',' || VALUE;
      RETURN ODCIConst.Success;
   END;

   MEMBER FUNCTION ODCIAggregateTerminate (self          IN     string_agg_type,
                                           returnValue      OUT VARCHAR2,
                                           flags         IN     NUMBER)
      RETURN NUMBER
   IS
   BEGIN
      returnValue := LTRIM (self.total, ',');
      RETURN ODCIConst.Success;
   END;

   MEMBER FUNCTION ODCIAggregateMerge (self   IN OUT string_agg_type,
                                       ctx2   IN     string_agg_type)
      RETURN NUMBER
   IS
   BEGIN
      self.total := self.total || ctx2.total;
      RETURN ODCIConst.Success;
   END;
END;
/


-- 最终要调用的方法
CREATE OR REPLACE FUNCTION stragg (input VARCHAR2)
   RETURN VARCHAR2
   PARALLEL_ENABLE
   AGGREGATE USING string_agg_type;
/

 

 

你可能感兴趣的:(oracle)