行列轉換通用過程

1.使用視圖

create or replace procedure row_to_col(tabname in varchar2,
                                                               group_col
in varchar2,in varchar2,
                                                               value_col
in varchar2,
                                                               Aggregate_func
in varchar2 default 'max',
                                                               colorder
in varchar2 default null,
                                                               roworder
in varchar2 default null,                                  

                            column_col

                                                               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 row_to_col;
參數:
tabname 需要進行行轉列操作的表名;
group_col 查詢結果要按某列或某些列分組的字段名;
column_col 要從行轉成列的字段;
value_col 需要聚合的值字段;
Aggregate_func 選用的聚合函數,可選,默認爲max;
colorder 行轉列後列的排序,可選;
roworder 行轉列後記錄的排序,可選;
when_value_null 若value_col字段的值聚合後爲空,則轉換成該值,可選;
viewname 創建的視圖名稱,可選,默認爲v_tmp。

舉例:
--測試數據
create table rowtocol_test as
select 2009 year,1 month,'部門1' dept,50000 expenditure from dual
union all select 2009,2,'部門1',20000 from dual
union all select 2009,2,'部門1',30000 from dual
union all select 2010,1,'部門1',35000 from dual
union all select 2009,2,'部門2',40000 from dual
union all select 2009,3,'部門2',25000 from dual
union all select 2010,2,'部門3',60000 from dual
union all select 2009,2,'部門3',15000 from dual
union all select 2009,2,'部門3',10000 from dual;

我現在想根據year和month分組,將部門轉成列。

SQL code
SQL> select * from rowtocol_test; YEAR MONTH DEPT EXPENDITURE ---------- ---------- ----- ----------- 2009 1 部門1 50000 2009 2 部門1 20000 2009 2 部門1 30000 2010 1 部門1 35000 2009 2 部門2 40000 2009 3 部門2 25000 2010 2 部門3 60000 2009 2 部門3 15000 2009 2 部門3 10000 9 rows selected SQL> execute row_to_col('rowtocol_test','year,month','dept','expenditure'); PL/SQL procedure successfully completed SQL> select * from v_tmp; YEAR MONTH 部門1 部門3 部門2 ---------- ---------- ---------- ---------- ---------- 2009 1 50000 2010 1 35000 2009 3 25000 2009 2 30000 15000 40000 2010 2 60000 SQL>


這個結果可能不是我們想要的,重新調用過程,使用幾個可選參數

SQL code
SQL> execute row_to_col('rowtocol_test','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0'); PL/SQL procedure successfully completed SQL> select * from v_tmp; YEAR MONTH 部門1 部門2 部門3 ---------- ---------- ---------- ---------- ---------- 2009 1 50000 0 0 2009 2 50000 40000 25000 2009 3 0 25000 0 2010 1 35000 0 0 2010 2 0 0 60000 SQL>


進行行轉列的也可以是視圖

SQL code
SQL> create view view_rowtocol as select * from rowtocol_test where year=2009; View created SQL> execute row_to_col('view_rowtocol','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0'); PL/SQL procedure successfully completed SQL> select * from v_tmp; YEAR MONTH 部門1 部門2 部門3 ---------- ---------- ---------- ---------- ---------- 2009 1 50000 0 0 2009 2 50000 40000 25000 2009 3 0 25000 0 SQL>


-----------------------------------------------------------

2.稍加修改,使用函數,返回遊標。或利用過程裏的傳出參數

create or replace function row_to_col_func(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
                                  )
return sys_refcursor
Authid
Current_User
as
  sqlstr
varchar2(2000):='select '||group_col||' ';
  c1 sys_refcursor;
  v1
varchar2(100);
  cur sys_refcursor;
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;
 
open cur for sqlstr||' from '||tabname||' group by '||group_col||case when roworder is not null then ' order by '||roworder end;
 
return cur;
end row_to_col_func;

在pl/sql dev中可以在sql窗口執行,查看結果

select
row_to_col_func(
'rowtocol_test','year,month','dept','expenditure',Aggregate_func => 'sum',colorder => 'dept',roworder => '1,2',when_value_null => '0')
from dual;

ROW_TO_COL_FUNC(
'ROWTOCOL_TEST
<Cursor>

YEAR    MONTH    部門1    部門2    部門3
2009    1    50000    0        0
2009    2    50000    40000    25000
2009    3    0        25000    0
2010    1    35000    0        0
2010    2    0        0        60000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章