1. 程式人生 > >oracle中用儲存過程進行動態行列轉換

oracle中用儲存過程進行動態行列轉換

oracle中用sql進行動態行列轉換:
存在以下兩個表
部門表:
部門ID 部門名稱
1         部門1
----------------------------------

員工表:

員工Id 員工名 性別 所屬部門
1 員工1 女 1
2 員工2 女 1
3 員工3 女 1
4 員工4 女 1
5 員工5 男 1
6 員工6 女 1
7 員工7 男 1
8 員工8 男 1
9 員工9 女 1
10 員工10 男 1
11 員工11 女 1
12 員工12 女 1
13 員工13 男 1
14 員工14 男 1
15 員工15 男 1
16 員工16 女 1
17 員工17 男 1
18 員工18 男 1
19 員工19 男 1
20 員工20 男 1

-------------------------------
通過sql查詢後結果顯示如下:
部門名 員工1 員工2 員工3 員工4 員工5 員工6 員工7 員工8 員工9 員工10 員工11 員工12 員工13 員工14 員工15 員工16 員工17 員工18 員工19 員工20
部門1 女 女 女 女 男 女 男 男 女 男 女 女 男 男 男 女 男 男 男 男

其中員工數是會變動的,所以橫向的列數是不定的,所以希望可以動態顯示列。

create or replace procedure procDepart is
sqlstr Clob := '';
sqlExtrData Clob :='';
tblCount number(10):=0;
begin
select count(*) into tblCount from user_tables utb where utb.table_name='temp_depart_report';
if tblCount>0 then
dbms_output.put_line('drop table temp_depart_report');
execute immediate 'drop table temp_depart_report';
end if;
sqlExtrData:='create  table temp_depart_report as (
select * from
(select tw.create_date,
       tc.claim_no,
       tt.description as taskName,
       tc.case_id,       
       tb.object_id,
       
       tr.flaged_counts,   
       
        tri.flag,
       tin.indicator_description
         
  from depart                  de,
       emp                     em,
       
 where de.depart_id = em.depart_id
   )tbl   
   )';
dbms_output.put_line('sqlExtrData:' ||sqlExtrData);




execute immediate sqlExtrData;
  select WM_CONCAT(''''||sex||'''') into sqlstr from (select distinct  t.sex from temp_depart_report t) t;
  
   sqlstr:='SELECT *
FROM temp_depart_report
  PIVOT (
  MAX(sex)
  FOR emp_no          
  IN  ('||sqlstr||')
  ) ORDER BY case_id asc';
  execute immediate sqlstr;
  dbms_output.put_line('sqlstr:'|| sqlstr);
  sqlstr := 'CREATE OR REPLACE VIEW v_depart_report  AS '|| sqlstr;
   --sqlRet :='select * from tmp_result';
  execute immediate sqlstr;
end procDepart;

特別需要注意的是:在pivot for子句中for 是需要按照哪一列轉換成行,in子句是哪些需要轉換成列,max(聚合函式子句)指的是行轉換成列後的值。

其中pivot,會隱式group by,如果在pivot子句前的select 語句查詢出來的結果所包含的記錄並不能group by時,將會顯示多行,行轉列後的值分別顯示在不同行。其中隱式group by時,group by的物件是除pivot聚合函式用到的欄位與pivot for子句用到的欄位外的所有欄位進行group by,然後將group by 的相同的資訊顯示在一行上,將行轉換成列的值拼接在group by物件的右方顯示。