[2022-10-07-mysql學習]行列互轉問題

行列互轉問題

行轉列

從數據的行拆出數據的列露氮,即把觀測的屬性(行)拆成一個變量(列)峡碉。
附注
1.其實我一開始覺得這是列轉行瞎惫,因為觀測的屬性由列排布變成了行,但一般都稱這種問題為行轉列胎源。
2.我對概念的理解可能有問題棉钧。

示例數據

https://leetcode.cn/problems/reformat-department-table/

id revenue month
1 8000 Jan
2 9000 Jan
3 1000 Feb
1 7000 Feb
1 6000 Mar

輸出每個部門每個月的薪資,即結果表格結構為:

id Jan_Revenue ... Dec_Revenue

允許空值涕蚤。

錯誤解答

select id,case when month='Jan' then revenue end as Jan_Revenue,case when month='Feb' then revenue end as Feb_Revenue,case when month='Mar' then revenue end as Mar_Revenue,case when month='Apr' then revenue end as Apr_Revenue,case when month='May' then Revenue end as May_Revenue,case when month='Jun' then revenue end as Jun_Revenue,case when month='Jul' then revenue end as Jul_Revenue,case when month='Aug' then revenue end as Aug_Revenue,case when month='Sep' then revenue end as Sep_Revenue,case when month='Oct' then revenue end as Oct_Revenue,case when month='Nov' then revenue end as Nov_Revenue,case when month='Dec' then revenue end as Dec_Revenue
from department;

運行結果(部分):

id Jan_Revenue Feb_Revenue ... Dec_Revenue
1 8000 NULL ... NULL
2 9000 NULL ... NULL
3 NULL 10000 ... NULL
1 NULL 7000 ... NULL
1 NULL NULL ... NULL

對于每個用戶分別輸出結果宪卿,不符合要求。
考慮合并結果万栅,一個自然的想法是聚合函數(注意:sum(NULL)=0):

select id,sum(case when month='Jan' then revenue end) as Jan_Revenue,
sum(case when month='Feb' then revenue end )as Feb_Revenue,
sum(case when month='Mar' then revenue end) as Mar_Revenue,
sum(case when month='Apr' then revenue end) as Apr_Revenue,
sum(case when month='May' then Revenue end) as May_Revenue,
sum(case when month='Jun' then revenue end) as Jun_Revenue,
sum(case when month='Jul' then revenue end) as Jul_Revenue,
sum(case when month='Aug' then revenue end) as Aug_Revenue,
sum(case when month='Sep' then revenue end) as Sep_Revenue,
sum(case when month='Oct' then revenue end) as Oct_Revenue,
sum(case when month='Nov' then revenue end) as Nov_Revenue,
sum(case when month='Dec' then revenue end) as Dec_Revenue
from department
group by id;

運行結果:

id Jan_Revenue Feb_Revenue ... Dec_Revenue
1 8000 7000 ... NULL
2 9000 NULL ... NULL
3 NULL 10000 ... NULL

這一結果符合要求佑钾。
另外的寫法:

select id,sum(if(month='Jan',revenue,null)) as Jan_Revenue,
sum(if(month='Feb',revenue,null))as Feb_Revenue,
sum(if(month='Mar',revenue,null)) as Mar_Revenue,
sum(if(month='Apr',revenue,null)) as Apr_Revenue,
sum(if(month='May',revenue,null)) as May_Revenue,
sum(if(month='Jun',revenue,null)) as Jun_Revenue,
sum(if(month='Jul',revenue,null)) as Jul_Revenue,
sum(if(month='Aug',revenue,null)) as Aug_Revenue,
sum(if(month='Sep',revenue,null)) as Sep_Revenue,
sum(if(month='Oct',revenue,null)) as Oct_Revenue,
sum(if(month='Nov',revenue,null)) as Nov_Revenue,
sum(if(month='Dec',revenue,null)) as Dec_Revenue
from department
group by id;

與case when的寫法思路相同,稍微簡潔一些烦粒。

思路總結

Step1. 用case when或if篩選出將要轉為變量的屬性休溶。
Step2.利用分組聚合函數sum匯總行。
語句框架:

select xx,sum(case when yy='屬性1'then zz end),...
from tb
group by xx;

select xx,sum(if(yy='屬性1',zz,null)),...
from tb
group by xx;

列轉行

列轉行是行轉列的逆過程扰她。
把上述結果再轉回原表格:

#為了方便兽掰,把行專列的結果存成一個臨時表
with tb as(
    select id,sum(if(month='Jan',revenue,null)) as Jan_Revenue,
sum(if(month='Feb',revenue,null))as Feb_Revenue,
sum(if(month='Mar',revenue,null)) as Mar_Revenue,
sum(if(month='Apr',revenue,null)) as Apr_Revenue,
sum(if(month='May',revenue,null)) as May_Revenue,
sum(if(month='Jun',revenue,null)) as Jun_Revenue,
sum(if(month='Jul',revenue,null)) as Jul_Revenue,
sum(if(month='Aug',revenue,null)) as Aug_Revenue,
sum(if(month='Sep',revenue,null)) as Sep_Revenue,
sum(if(month='Oct',revenue,null)) as Oct_Revenue,
sum(if(month='Nov',revenue,null)) as Nov_Revenue,
sum(if(month='Dec',revenue,null)) as Dec_Revenue
from department
group by id)
#列轉行
select id,Jan_Revenue as Revenue,'Jan' as month
from tb
union all
select id,Feb_Revenue as Revenue,'Feb' as month
from tb
union all
select id,Mar_Revenue as Revenue,'Mar' as month
from tb
union all
select id,Apr_Revenue as Revenue,'Apr' as month
from tb
union all
select id,May_Revenue as Revenue,'May' as month
from tb
union all
select id,Jun_Revenue as Revenue,'Jun' as month
from tb
union all
select id,Jul_Revenue as Revenue,'Jul' as month
from tb
union all
select id,Aug_Revenue as Revenue,'Aug' as month
from tb
union all
select id,Sep_Revenue as Revenue,'Sep' as month
from tb
union all
select id,Oct_Revenue as Revenue,'Oct' as month
from tb
union all
select id,Nov_Revenue as Revenue,'Nov' as month
from tb
union all
select id,Dec_Revenue as Revenue,'Dec' as month
from tb;

運行結果:

id revenue month
1 8000 Jan
2 9000 Jan
3 NULL Jan
1 7000 Feb
2 NULL Feb
3 10000 Feb
.. .. ..

其中含有很多NULL,不是原來的表徒役,考慮去除孽尽。

with tb as(
    select id,sum(if(month='Jan',revenue,null)) as Jan_Revenue,
sum(if(month='Feb',revenue,null))as Feb_Revenue,
sum(if(month='Mar',revenue,null)) as Mar_Revenue,
sum(if(month='Apr',revenue,null)) as Apr_Revenue,
sum(if(month='May',revenue,null)) as May_Revenue,
sum(if(month='Jun',revenue,null)) as Jun_Revenue,
sum(if(month='Jul',revenue,null)) as Jul_Revenue,
sum(if(month='Aug',revenue,null)) as Aug_Revenue,
sum(if(month='Sep',revenue,null)) as Sep_Revenue,
sum(if(month='Oct',revenue,null)) as Oct_Revenue,
sum(if(month='Nov',revenue,null)) as Nov_Revenue,
sum(if(month='Dec',revenue,null)) as Dec_Revenue
from department
group by id)
#列轉行
select *
from(
select id,Jan_Revenue as Revenue,'Jan' as month
from tb
union all
select id,Feb_Revenue as Revenue,'Feb' as month
from tb
union all
select id,Mar_Revenue as Revenue,'Mar' as month
from tb
union all
select id,Apr_Revenue as Revenue,'Apr' as month
from tb
union all
select id,May_Revenue as Revenue,'May' as month
from tb
union all
select id,Jun_Revenue as Revenue,'Jun' as month
from tb
union all
select id,Jul_Revenue as Revenue,'Jul' as month
from tb
union all
select id,Aug_Revenue as Revenue,'Aug' as month
from tb
union all
select id,Sep_Revenue as Revenue,'Sep' as month
from tb
union all
select id,Oct_Revenue as Revenue,'Oct' as month
from tb
union all
select id,Nov_Revenue as Revenue,'Nov' as month
from tb
union all
select id,Dec_Revenue as Revenue,'Dec' as month
from tb
)tb2
where revenue is not null;

運行結果:

id revenue month
1 8000 Jan
2 9000 Jan
1 7000 Feb
3 10000 Feb
1 6000 Mar

返回了原表。

思路總結

Step1 分別取出各觀測各屬性的數據忧勿,生成屬性外其它列與屬性列(示例中的month)泻云。
Step1 用union all合并觀測艇拍。
語句框架:

select xx,yy as 'name1',屬性1 as 'name2'
from tb
union all
select xx,yy as 'name1',屬性2 as 'name2' 
from tb
union all
...
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末狐蜕,一起剝皮案震驚了整個濱河市宠纯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌层释,老刑警劉巖婆瓜,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贡羔,居然都是意外死亡廉白,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門乖寒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猴蹂,“玉大人,你說我怎么就攤上這事楣嘁“跚幔” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵逐虚,是天一觀的道長聋溜。 經常有香客問我,道長叭爱,這世上最難降的妖魔是什么撮躁? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任驱富,我火速辦了婚禮马昨,結果婚禮上,老公的妹妹穿的比我還像新娘摄乒。我一直安慰自己漓穿,他們只是感情好嗤军,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著器净,像睡著了一般型雳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上山害,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天纠俭,我揣著相機與錄音,去河邊找鬼浪慌。 笑死冤荆,一個胖子當著我的面吹牛,可吹牛的內容都是我干的权纤。 我是一名探鬼主播钓简,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乌妒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了外邓?” 一聲冷哼從身側響起撤蚊,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎损话,沒想到半個月后侦啸,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡丧枪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年光涂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拧烦。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忘闻,死狀恐怖,靈堂內的尸體忽然破棺而出恋博,到底是詐尸還是另有隱情齐佳,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布交播,位于F島的核電站重虑,受9級特大地震影響,放射性物質發(fā)生泄漏秦士。R本人自食惡果不足惜缺厉,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隧土。 院中可真熱鬧提针,春花似錦、人聲如沸曹傀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皆愉。三九已至嗜价,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幕庐,已是汗流浹背久锥。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留异剥,地道東北人瑟由。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像冤寿,于是被迫代替她去往敵國和親歹苦。 傳聞我的和親對象是個殘疾皇子青伤,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內容