若有一個table(income_record),記載著三項產品,每項產品各自有三個人做銷售,那麼它
的table我是把它設定成五個欄位,分別為YEAR、MONTH、ID、SOURCE、INCOME
。ID表示一個人、SOURCE表示產品種類、INCOME表示收入等。
資料呈現方式如下:
所下的SQL只要select * from income_record即可。
重點來了,假設呈現的形式改成以種類一次對應所有人及當下的income,那麼資料的列數
將濃縮成三行而已,如下:
說明一:
將人的ID組出一個順序並賦予編號,如此一來當完整資料的table與該特定組成的table做
JOIN時,將可以將每個人塞至對應的column內,如下:
兩個table join的條件為ID相同的,而group針對YEAR、MONTH、SOURCE,再來就是要呈
現的欄位,由於設定group項目不針對ID、INCOME,因此需配合彙總函數的使用,在這邊
假如從另一組成的table得到的rank_id = 1,則印其相關的ID及INCOME,以此類推再比較其
它排名是否有符合的資料!
PS. 缺點是,這些撈取欄位的rank比較是寫死的,因此若超過三個人,以現有的SQL則會
只列出三個人的合併資料,因此可設定一範圍來含括。
的table我是把它設定成五個欄位,分別為YEAR、MONTH、ID、SOURCE、INCOME
。ID表示一個人、SOURCE表示產品種類、INCOME表示收入等。
資料呈現方式如下:
所下的SQL只要select * from income_record即可。
重點來了,假設呈現的形式改成以種類一次對應所有人及當下的income,那麼資料的列數
將濃縮成三行而已,如下:
因此,在這邊要討論的議題是,如何以產品的角度來看對應所有人的資料。
組成的SQL如下,還真有點長XD
select T.YEAR, T.MONTH, T.SOURCE,
MAX(CASE WHEN tt.ID_Rank = '1' then T.ID else '' end) as ID1,
SUM(CASE WHEN tt.ID_Rank = '1' then T.INCOME else 0 end) as INCOME1,
MAX(CASE WHEN tt.ID_Rank = '2' then T.ID else '' end) as ID2,
SUM(CASE WHEN tt.ID_Rank = '2' then T.INCOME else 0 end) as INCOME2,
MAX(CASE WHEN tt.ID_Rank = '3' then T.ID else '' end) as ID3,
SUM(CASE WHEN tt.ID_Rank = '3' then T.INCOME else 0 end) as INCOME3
from income_record T
left join(
select t1.ID as ID, COUNT(*) as ID_Rank from
(
select ID
from
income_record
group by id
)
t1 left join
(
select id
from income_record
group by id
)
t2 on (t1.ID >= t2.ID)
group by t1.ID
) tt on T.ID = tt.ID
group by T.YEAR, T.MONTH, T.SOURCE
說明一:
將人的ID組出一個順序並賦予編號,如此一來當完整資料的table與該特定組成的table做
JOIN時,將可以將每個人塞至對應的column內,如下:
select t1.ID as ID, COUNT(*) as ID_Rank from
(
select ID
from
income_record
group by id
)
t1 left join
(
select id
from income_record
group by id
)
t2 on (t1.ID >= t2.ID)
group by t1.ID
s001為1由於t1.ID >= t2.ID,即s001 只會滿足 s001 >=s001,因此只會有一列;而s003同時
會滿足s001、s002、s003,因此s003就會有三列,對應成rank該好會有一個數字排名。
說明二:
緊接著,就是做一般table的撈取,並與剛剛的table組成做join的動作,如下:
select T.YEAR, T.MONTH, T.SOURCE,
MAX(CASE WHEN tt.ID_Rank = '1' then T.ID else '' end) as ID1,
SUM(CASE WHEN tt.ID_Rank = '1' then T.INCOME else 0 end) as INCOME1,
MAX(CASE WHEN tt.ID_Rank = '2' then T.ID else '' end) as ID2,
SUM(CASE WHEN tt.ID_Rank = '2' then T.INCOME else 0 end) as INCOME2,
MAX(CASE WHEN tt.ID_Rank = '3' then T.ID else '' end) as ID3,
SUM(CASE WHEN tt.ID_Rank = '3' then T.INCOME else 0 end) as INCOME3
from income_record T
left join(
省略...
) tt on T.ID = tt.ID
group by T.YEAR, T.MONTH, T.SOURCE
兩個table join的條件為ID相同的,而group針對YEAR、MONTH、SOURCE,再來就是要呈
現的欄位,由於設定group項目不針對ID、INCOME,因此需配合彙總函數的使用,在這邊
假如從另一組成的table得到的rank_id = 1,則印其相關的ID及INCOME,以此類推再比較其
它排名是否有符合的資料!
PS. 缺點是,這些撈取欄位的rank比較是寫死的,因此若超過三個人,以現有的SQL則會
只列出三個人的合併資料,因此可設定一範圍來含括。
留言
張貼留言