zoukankan      html  css  js  c++  java
  • Oracle 行转列(不固定行数的行转列,动态)(转)

    http://bbs.csdn.net/topics/330039676

    SQLSERVER :行列转换例子:  http://www.cnblogs.com/gaizai/p/3753296.html#_labelFour

    1. Oracle 11g之后新增了行列转换的函数 pivot 和 unpivot 大大简化了行列转换处理。

    2. 在Oracle 10g及以前版本,一般是通过各种SQL进行行列转换,列入下面例子:

    create or replace procedure P_row_to_col(tabname         in varchar2,
                                           group_col       in varchar2,
                                           column_col      in varchar2,
                                           value_col       in varchar2,
                                           Aggregate_func  in varchar2 default 'max',
                                           colorder        in varchar2 default null,
                                           roworder        in varchar2 default null,
                                           when_value_null in varchar2 default null,
                                           viewname        in varchar2 default 'v_tmp')
      Authid Current_User as sqlstr varchar2(2000) := 'create or replace view ' || viewname || ' as select ' || group_col || ' '; 
      c1 sys_refcursor; 
      v1 varchar2(100);
    begin
    open c1 for 'select distinct ' || column_col || ' from ' || tabname || case when colorder is
    not null then ' order by ' || colorder
    end; 
    loop fetch c1 into v1; 
    exit when c1%notfound; 
    sqlstr := sqlstr || chr(10) || ',' || case when when_value_null is
    not null then 'nvl('
    end || Aggregate_func || '(decode(to_char(' || column_col || '),''' || v1 || ''',' || value_col || '))' || case when when_value_null is
    not null then chr(44) || when_value_null || chr(41)
    end || '"' || v1 || '"';
    end loop; 
    close c1; 
    sqlstr := sqlstr || ' from ' || tabname || ' group by ' || group_col || case when roworder is
    not null then ' order by ' || roworder
    end; 
    execute immediate sqlstr;
    end P_row_to_col;
    
    --测试数据 
    create table rowtocol_test as 
    select 2009 year,1 month,'AAA1' dept,50000 expenditure from dual 
    union all select 2009,2,'AAA1',20000 from dual 
    union all select 2009,2,'AAA1',30000 from dual 
    union all select 2010,1,'AAA1',35000 from dual 
    union all select 2009,2,'BBB2',40000 from dual 
    union all select 2009,3,'BBB2',25000 from dual 
    union all select 2010,2,'DDD3',60000 from dual 
    union all select 2009,2,'DDD3',15000 from dual 
    union all select 2009,2,'DDD3',10000 from dual; 
    
    select * from rowtocol_test; 

    --执行测试

    begin
    p_row_to_col(
    'rowtocol_test','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0')
    ;
    end;

    select * from v_tmp;
    ================================================================================================================





    例子二 三:

    --测试数据 
    create table t (XH varchar2(10), DDATE date, SXF int); 
    insert into t select 1,sysdate,10 from dual 
    union all select 1,sysdate+1,14 from dual 
    union allselect 1,sysdate+2,23 from dual 
    union allselect 2,sysdate,21 from dual 
    union allselect 2,sysdate+1,24 from dual 
    union allselect 3,sysdate,13 from dual 
    union allselect 3,sysdate+1,22 from dual;
     -- 
     create or replace package sp_test istype ResultData is ref cursor; 
     procedure getRstData( rst out ResultData); end sp_test; 
     / 
     create or replace package body sp_test isprocedure getRstData( rst out ResultData) 
     is begin 
     declare cursor cur is select distinct (DDATE) from t; 
     tmp_ddate date; 
     str varchar2(4000); 
     beginstr:='select xh'; 
     open cur; 
     loop fetch cur into tmp_ddate; 
     exit when cur%notfound; 
     str:=str||',sum(decode(to_char(ddate,''yyyymmdd''),'||chr(39)||to_char(tmp_ddate,'yyyymmdd')||chr(39)||',sxf,0)) "'||to_char(tmp_ddate,'yyyymmdd')||'"'; 
     end loop; 
     str:=str||' from t group by xh'; 
     -- 
     dbms_output.put_line(str); 
     close cur; 
     open rst for str; end; 
     end;
      end sp_test; 
      / 
      --输出结果 
      1 10 14 
      23 2 21 
      24 0 3 
      13 22 0
      
      
      ========================
      例子三:
      ------------建表
      CREATE TABLE TEST(WL VARCHAR2(10),XYSL INTEGER,XYCK VARCHAR2(10),XCLCK VARCHAR2(10),XCLCKSL INTEGER,PC INTEGER);
      ------------ 第一部分测试数据
      INSERT INTO TEST VALUES('A1', 2, 'C1', 'C1' ,        20,         123); 
      INSERT INTO TEST VALUES('A1', 2, 'C1', 'C2' ,        30,         111); 
      INSERT INTO TEST VALUES('A1', 2, 'C1', 'C2' ,        20,         222); 
      INSERT INTO TEST VALUES('A1', 2, 'C1', 'C3' ,        10,         211); 
      INSERT INTO TEST VALUES('A2', 3, 'C4', 'C1' ,        40,         321); 
      INSERT INTO TEST VALUES('A2', 3, 'C4', 'C4' ,        50,         222); 
      INSERT INTO TEST VALUES('A2', 3, 'C4', 'C4' ,        60,         333); 
      INSERT INTO TEST VALUES('A2', 3, 'C4', 'C5' ,        70,         223);
      COMMIT;
      --------------------  动态生成结果表
      DECLARE  V_SQL VARCHAR2(2000);  
      CURSOR CURSOR_1 IS    SELECT DISTINCT T.XCLCK      FROM TEST T     ORDER BY XCLCK; 
      BEGIN  V_SQL := 'SELECT WL,XYSL,XYCK';  
      FOR V_XCLCK IN CURSOR_1  
        LOOP    V_SQL := V_SQL || ',' || 'SUM(DECODE(XCLCK,''' || V_XCLCK.XCLCK ||  ''',XCLCKSL,0)) AS ' || V_XCLCK.XCLCK;  
        END LOOP;  
        V_SQL := V_SQL || ' FROM TEST GROUP BY WL,XYSL,XYCK ORDER BY WL,XYSL,XYCK'; 
      --DBMS_OUTPUT.PUT_LINE(V_SQL);
      V_SQL := 'CREATE TABLE RESULT  AS '||  V_SQL;
      --DBMS_OUTPUT.PUT_LINE(V_SQL);
      EXECUTE IMMEDIATE V_SQL;
      END;
      --------------- 结果
      SELECT * FROM RESULT T;
  • 相关阅读:
    1.vue-1
    7.Docker -- 虚拟服务器
    11.Django -- 中间件
    10.Django -- csrf -- 文件上传
    9.djang -- cookie和session
    8.Django --Ajax
    YOLO v1原理详解
    带你一文读懂Faster RCNN论文
    Week13
    Week12
  • 原文地址:https://www.cnblogs.com/yelisen2011/p/3457519.html
Copyright © 2011-2022 走看看