SQL Server - 利用SQL語法做資料合併

若有一個table(income_record),記載著三項產品,每項產品各自有三個人做銷售,那麼它

的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則會

只列出三個人的合併資料,因此可設定一範圍來含括。

留言