Oracle SQL函式pivot、unpivot轉置函式實現行轉列、列轉行
阿新 • • 發佈:2019-01-30
函式PIVOT、UNPIVOT轉置函式實現行轉列、列轉行,效果如下圖所示:
1.PIVOT為行轉列,從圖示的左邊到右邊
2.UNPIVOT為列轉行,從圖示的右邊到左邊
3.左邊為縱表,結構簡單,易擴充套件
4.右邊為橫表,展示清晰,方便查詢
5.很多時候業務表為縱表,但是統計分析需要的結果如右邊的橫表,這時候就需要用到轉置函數了
示例圖表:
Pivot語法:
SELECT .... FROM <table-expr> PIVOT ( aggregate-function(<column>) FOR <pivot-column> IN (<value1>, <value2>,..., <valuen>) ) AS <alias> WHERE .....
注意:
FOR <pivot-column>
這個是不支援表示式的,如果需要,請通過子查詢或者檢視先預處理。Pivot
例子1:先構造一個子查詢,然後根據CHANNEL列進行轉置,源表sales_view裡面可能有很多列,不需要列先通過子查詢過濾掉再進行轉置。另外轉置後的列指定了別名,值是對amount_sold列的彙總。
SELECT * FROM (SELECT product, channel, amount_sold FROM sales_view ) S PIVOT (SUM(amount_sold) FOR CHANNEL IN (3 AS DIRECT_SALES, 4 AS INTERNET_SALES, 5 AS CATALOG_SALES, 9 AS TELESALES)) ORDER BY product; PRODUCT DIRECT_SALES INTERNET_SALES CATALOG_SALES TELESALES ---------------------- ------------ -------------- ------------- --------- ... Internal 6X CD-ROM 229512.97 26249.55 Internal 8X CD-ROM 286291.49 42809.44 Keyboard Wrist Rest 200959.84 38695.36 1522.73 ...
例子2:基於多列進行轉置,下面例子是基於channel、quarter兩列進行轉置
SELECT * FROM (SELECT product, channel, quarter, quantity_sold FROM sales_view ) PIVOT (SUM(quantity_sold) FOR (channel, quarter) IN ((5, '02') AS CATALOG_Q2, (4, '01') AS INTERNET_Q1, (4, '04') AS INTERNET_Q4, (2, '02') AS PARTNERS_Q2, (9, '03') AS TELE_Q3 ) ); PRODUCT CATALOG_Q2 INTERNET_Q1 INTERNET_Q4 PARTNERS_Q2 TELE_Q3 ------- ---------- ----------- ----------- ----------- ------- ... Bounce 347 632 954 ... Smash Up Boxing 129 280 560 ... Comic Book Heroes 47 155 275 ...
例子3:對多列的值進行彙總計算,以下是基於channel例進行轉置,然後對amount_sold和quantity_sold兩列進行合計運算
SELECT *
FROM
(SELECT product, channel, amount_sold, quantity_sold
FROM sales_view
) PIVOT (SUM(amount_sold) AS sums,
SUM(quantity_sold) AS sumq
FOR channel IN (5, 4, 2, 9)
)
ORDER BY product;
PRODUCT 5_SUMS 5_SUMQ 4_SUMS 4_SUMQ 2_SUMS 2_SUMQ 9_SUMS 9_SUMQ
------------- ------ ------ ------ ------ ------ ------ ------ ------
O/S Doc Set English 142780.36 3081 381397.99 8044 6028.66 134
O/S Doc Set French 55503.58 1192 132000.77 2782
...
Unpivot
unpivot是pivot的相反操作,進行的是列轉行例子1:先看源表結構,for子句指定將(Q1_SUMQ, Q2_SUMQ, Q3_SUMQ, Q4_SUMQ)這4列轉置為行,
for子句之前的quantity_sold是4列轉置後的列名,
decode還定義了每列轉置為行後新標示列的值,這個等下看第2個例子可以看到,也可以在 in 子句後面加 as 指定別名。
UNPIVOT INCLUDE NULLS 指定空值也進行轉置,如果是EXCLUDE NULLS 將忽略空值。
SELECT *
FROM pivotedTable
ORDER BY product;
PRODUCT Q1_SUMQ Q1_SUMA Q2_SUMQ Q2_SUMA Q3_SUMQ Q3_SUMA Q4_SUMQ Q4_SUMA
--------------- ------- ------- ------- -------- ------- -------- ------- ---------
1.44MB External 6098 58301.33 5112 49001.56 6050 56974.3 5848 55341.28
128MB Memory 1963 110763.63 2361 132123.12 3069 170710.4 2832 157736.6
17" LCD 1492 1812786.94 1387 1672389.06 1591 1859987.66 1540 1844008.11
SELECT product, DECODE(quarter, 'Q1_SUMQ', 'Q1', 'Q2_SUMQ', 'Q2', 'Q3_SUMQ', 'Q3',
'Q4_SUMQ', 'Q4') AS quarter, quantity_sold
FROM pivotedTable
UNPIVOT INCLUDE NULLS
(quantity_sold
FOR quarter IN (Q1_SUMQ, Q2_SUMQ, Q3_SUMQ, Q4_SUMQ))
ORDER BY product, quarter;
PRODUCT QUARTER QUANTITY_SOLD
------- -- -------------
1.44MB External 3.5" Diskette Q1 6098
1.44MB External 3.5" Diskette Q2 5112
1.44MB External 3.5" Diskette Q3 6050
1.44MB External 3.5" Diskette Q4 5848
128MB Memory Card Q1 1963
128MB Memory Card Q2 2361
128MB Memory Card Q3 3069
128MB Memory Card Q4 2832
...
例子2:轉置多列的情況
SELECT product, quarter, quantity_sold, amount_sold
FROM pivotedTable
UNPIVOT INCLUDE NULLS
(
(quantity_sold, amount_sold)
FOR quarter IN ((Q1_SUMQ, Q1_SUMA) AS 'Q1', (Q2_SUMQ, Q2_SUMA) AS 'Q2', (Q3_SUMQ, Q3_SUMA) AS 'Q3', (Q4_SUMQ, Q4_SUMA) AS 'Q4'))
ORDER BY product, quarter;
PRODUCT QU QUANTITY_SOLD AMOUNT_SOLD
----------------------------- -- ------------- ------------
1.44MB External 3.5" Diskette Q1 6098 58301.33
1.44MB External 3.5" Diskette Q2 5112 49001.56
1.44MB External 3.5" Diskette Q3 6050 56974.3
1.44MB External 3.5" Diskette Q4 5848 55341.28
128MB Memory Card Q1 1963 110763.63
128MB Memory Card Q2 2361 132123.12
128MB Memory Card Q3 3069 170710.4
128MB Memory Card Q4 2832 157736.6
總結,基本上按照語法套用即可,注意將源表非相關列先過濾掉,可是是子查詢,也可以是檢視。
最後試試解決這個問題吧,看你是否真的懂了!
http://blog.csdn.net/seandba/article/details/72629724
以上內容均來自Oracle11g官方文件,我只是搬運工。。。
Oracle® Database Data Warehousing Guide
11g Release 2 (11.2)
E25554-01