如何使用 PIVOT「扭轉」查詢的結果?
PIVOT 翻轉Table的方法
在Oracle 和 SQLServer 都有現成的PIvot 樞紐分析函式可以用~
公式如下
1 |
|
PIVOT 內放 運算集合
For 一個你要翻轉的欄位
IN 你對應到select 的欄位
As 為這新的PIVOT Table命名
TABLE
假設我們DB有一張表 叫ONETABLE,
KIND 種類有 101,102,103 三種
table 內容如下
TYPE1 | TYPE2 | KIND | CREATEDATE | DELMK |
---|---|---|---|---|
A | B | 101 | 20220401 | |
A | 102 | 20220505 | D | |
A | 101 | 20220601 | ||
A | 102 | 20220601 | ||
B | 102 | 20220602 | ||
B | A | 102 | 20220608 |
需求
📊需求是要得到一張過濾掉條件後的表格
統計每種TYPE的每種KIND次數加總
期望要長這樣
101 | 102 | 103 | |
---|---|---|---|
A | 1 | 2 | 0 |
B | 0 | 2 | 0 |
原先 SQL
那就開始吧~~~
JAVA 連接資料庫連接 這段跳過
只需知道我們傳入三個欄位進DB查詢
1.TYPE類型 (LIKE A,B,C)
2.日期的起月
3.日期的迄月
1 |
|
查出來的 資料應該會長這樣
YOURTYPE | KIND | COUNT |
---|---|---|
A | 102 | 1 |
A | 102 | 1 |
A | 101 | 1 |
註(根據大表來看):
第一筆資料:CREATEDATE 時段範圍不對 X
第二筆資料:DELMK 為D註記 (表示已刪除) 已排除X
第三筆資料:TYPE1符合A , 有一筆KIND 101
第四筆資料:TYPE1符合A , 有一筆KIND 102
第五筆資料:TYPE1不符合
第六筆資料:雖TYPE1不符,但是TYPE2 符合A , 有一筆KIND 102
困擾
這樣查出來 會是一個 根據TYPE=A 的多筆LIST
再由JAVA 跑FOR迴圈 一一塞入對應值 這也是我原先的做法~ (很笨 但不用多想XD)
假設找出來 A的LIST 有10筆 迴圈就要跑十次
然後 TYPE有5種 合計就是5*10=50次
期望
我期望查出來 是一個 根據TYPE=A 的單一筆統計好各KIND次數的資料
希望查出來的表是長這樣
KIND1 | KIND2 | KIND3 |
---|---|---|
1 | 2 | 0 |
這樣JAVA 不用跑回圈 永遠只有單一筆 統計好各KIND次數的資料
假設找出來 TYPE有5種 JAVA不用迴圈 只需要 5次
解決方法- 使用 PIVOT 「扭轉」查詢的結果 (把SQL查詢成果(直式),轉成(橫式)展示格式)
注意:
1.如果只用kind的101,102,103當成欄位名稱,JAVA無法對應,因為JAVA的欄位命名,不能以數字為開頭,需要另訂名字
2.pivot 不能用nvl,只能加在找完後的上方欄位
1 |
|
BINGO~~~
查出來 type=A的就會是
KIND1 | KIND2 | KIND3 |
---|---|---|
1 | 2 | 0 |
回到需求
上述SQL 可以得到 第一列的 A
再來JAVA 只要在CALL一次 可以得到 B的這列
因為需要分開統計 所以目前僅想到這作法 沒辦法一次全部 條件不同 不過也省下很多工了XD~
101 | 102 | 103 | |
---|---|---|---|
A | 1 | 2 | 0 |
B | 0 | 2 | 0 |
註:為何用 sum(count),而不是用count(count) ?
上面說到原本SQL查出來長這樣
YOURTYPE | KIND | COUNT |
---|---|---|
A | 102 | 1 |
A | 102 | 1 |
A | 101 | 1 |
首先我們用KIND 當成查出來的欄位
所以以KIND角度來看~
使用sum(count) ?
原因是把這個KIND的COUNT 加起來
也就是
101 -> 1
102 -> 1+1=2
那為何不用 count(count) ?
以KIND角度來看 count 是指
針對 KIND=101 這只有一筆資料 所以count =1
KIND=102 這也只有一筆資料 所以count =1
結語
技術債還是要還XD
剛好維護案看到一年半前自已寫的CODE
那時候也沒有研究特別得寫法
SA開的SQL就直接給他下去 手寫得很酸
現在終於有重構~ 靠著GOOGLE大神學了新寫法!
希望對大家有幫助~~~
這段SQL 有寫在線上測試DB 歡迎實測~~~
http://sqlfiddle.com/#!4/a2ce3f/10
參考stackoverflow這篇
Using pivot on multiple columns of an Oracle row :
https://stackoverflow.com/questions/23939244/using-pivot-on-multiple-columns-of-an-oracle-row
參考:
https://dotblogs.com.tw/SteveLiu/2019/05/21/173803
補充:如果要用 MySQL 和 Postgresql 請參考此篇(我沒用過XD)
https://dotblogs.com.tw/daniel/2018/05/09/172804