2012-11-16 163 views
1

我正在使用oracle 10g。 我有一個臨時表TEMP。Oracle 10g樞軸

TEMP具有以下結構: -

USER COUNT TYPE 
---- ----- ---- 
    1 10 T1 
    2 21 T2 
    3 45 T1 
    1  7 T1 
    2  1 T3 

我需要一個查詢,它會顯示所有類型都有列名和類型可以有任何價值一樣T1, T2,..Tn和結果會是這樣的: -

USER T1 T2 T3 
---- -- -- -- 
    1 17 0 1 
    2 0 21 1 
    3 45 0 0 

和用戶列將顯示所有用戶和T1, T2列將顯示類型的總數。

+0

不知道如何做到這一點 – F11

+0

你需要給出一個更明顯的例子你的結果應與樣本表一致。 –

+0

@JoachimIsaksson請查看編輯問題 – F11

回答

5

在Oracle 10g中,沒有PIVOT功能,但你可以使用聚合與CASE複製它:

select usr, 
    sum(case when tp ='T1' then cnt else 0 end) T1, 
    sum(case when tp ='T2' then cnt else 0 end) T2, 
    sum(case when tp ='T3' then cnt else 0 end) T3 
from temp 
group by usr; 

SQL Fiddle with Demo

如果你的Oracle 11g +,那麼你可以使用PIVOT功能:

select * 
from temp 
pivot 
(
    sum(cnt) 
    for tp in ('T1', 'T2', 'T3') 
) piv 

SQL Fiddle with Demo

如果你有一個未知的數值進行改造的,那麼你可以創建一個過程來產生這個動態的版本:

CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor) 
as 
    sql_query varchar2(1000) := 'select usr '; 

    begin 
     for x in (select distinct tp from temp order by 1) 
     loop 
      sql_query := sql_query || 
       ' , sum(case when tp = '''||x.tp||''' then cnt else 0 end) as '||x.tp; 

       dbms_output.put_line(sql_query); 
     end loop; 

     sql_query := sql_query || ' from temp group by usr'; 

     open p_cursor for sql_query; 
    end; 
/

然後執行該代碼:

variable x refcursor 
exec dynamic_pivot(:x) 
print x 

結果所有版本是相同的:

| USR | T1 | T2 | T3 | 
---------------------- 
| 1 | 17 | 0 | 0 | 
| 2 | 0 | 21 | 1 | 
| 3 | 45 | 0 | 0 | 

編輯:基於您的評論,如果你想有一個Total˚F ield,最簡單的方法是將查詢放置另一個SELECT類似這樣的內部:

select usr, 
    T1 + T2 + T3 as Total, 
    T1, 
    T2, 
    T3 
from 
(
    select usr, 
    sum(case when tp ='T1' then cnt else 0 end) T1, 
    sum(case when tp ='T2' then cnt else 0 end) T2, 
    sum(case when tp ='T3' then cnt else 0 end) T3 
    from temp 
    group by usr 
) src; 

SQL Fiddle with Demo

+0

,我需要在USER和T1之間的一列顯示類型的總數,如何通過查詢來完成。輸出應該是: - | USR |合計| T1 | T2 | T3 | ----------------------總列將顯示T1,T2,T3的總和 – F11

+0

@您最好的選擇是將您的查詢置於另一個選擇內,類似到這個演示 - http://www.sqlfiddle.com/#!4/a42bb/5 – Taryn

+0

,我需要一個更多的幫助。我必須顯示所有行的總數與header.Total將被添加與頭在哪裏總和是sum像User | Total_Total | T1_Total | T2_Total | – F11

2

下面是創建表的代碼:

CREATE TABLE TBL_TEMP 
(
    USR NUMBER 
    ,CNT NUMBER 
    ,TP VARCHAR2 (10) 
); 

INSERT INTO TBL_TEMP VALUES (1,10,'T1'); 
INSERT INTO TBL_TEMP VALUES (2,21,'T2'); 
INSERT INTO TBL_TEMP VALUES (3,45,'T1'); 
INSERT INTO TBL_TEMP VALUES (1,7,'T1'); 
INSERT INTO TBL_TEMP VALUES (2,1,'T3'); 

而且,這裏是你的請求代碼:

SELECT T1.USR 
     ,SUM (T1) T1 
     ,SUM (T2) T2 
     ,SUM (T3) T3 
    FROM (SELECT DISTINCT USR FROM TBL_TEMP) T1 
     ,(SELECT T2.USR 
       ,DECODE (T2.TP, 'T1', T2.CNT, 0) T1 
       ,DECODE (T2.TP, 'T2', T2.CNT, 0) T2 
       ,DECODE (T2.TP, 'T3', T2.CNT, 0) T3 
      FROM TBL_TEMP T2) T2 
    WHERE T1.USR = T2.USR 
GROUP BY T1.USR; 

而且,結果是你想要的。

在SQL小提琴菱格紋它here

+0

+1。對於未來的用戶,[Oracle 11g引入了透視功能](http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm#CHDCEJJE) – danihp

0

請檢查查詢:

SET SERVEROUTPUT ON; 
DECLARE 
CURSOR V_CUR IS 
SELECT DISTINCT "TYPE" FROM temp_tbl; 

V_QUERY CLOB; 
V_COLUMNHEADING CLOB; 
V_ROW V_CUR%ROWTYPE; 
BEGIN 
    OPEN V_CUR; 
    LOOP 
    FETCH V_CUR INTO V_ROW; 
    EXIT WHEN V_CUR%NOTFOUND; 
    V_COLUMNHEADING:=CONCAT(V_COLUMNHEADING,''''||V_ROW."TYPE"||''' AS "'||V_ROW."TYPE"||'",'); 
    END LOOP; 

    IF NVL(V_COLUMNHEADING,' ') <> ' ' THEN 
     V_COLUMNHEADING := SUBSTR(V_COLUMNHEADING,0,LENGTH(V_COLUMNHEADING)-1); 
    END IF; 

    V_QUERY := CONCAT(V_QUERY,'select * from (select * from temp_tbl)a pivot (sum("COUNT")for "TYPE" in ('||V_COLUMNHEADING||'))b;'); 
    DBMS_OUTPUT.PUT_LINE(V_QUERY); 
END ; 

要到位DBMS_OUTPUT.PUT_LINE(V_QUERY);,其中CUR_TURN_TIME是在包中聲明的光標選擇數據,使用的語句OPEN CUR_TURN_TIME FOR V_QUERY;