SQL中如何將行轉(zhuǎn)成列詳解
天天這需求就神奇?。。?!
SQL中怎么將行轉(zhuǎn)成列?
我們以MySQL數(shù)據(jù)庫(kù)為例,來(lái)說(shuō)明行轉(zhuǎn)列的實(shí)現(xiàn)方式。
首先,假設(shè)我們有一張分?jǐn)?shù)表(tb_score),表中的數(shù)據(jù)如下圖:

然后,我們?cè)賮?lái)看一下轉(zhuǎn)換之后需要得到的結(jié)果,如下圖:

可以看出,這里行轉(zhuǎn)列是將原來(lái)的subject字段的多行內(nèi)容選出來(lái),作為結(jié)果集中的不同列,并根據(jù)userid進(jìn)行分組顯示對(duì)應(yīng)的score。通常,我們有兩種方式來(lái)實(shí)現(xiàn)這種轉(zhuǎn)換。
1. 使用 CASE…WHEN…THEN 語(yǔ)句實(shí)現(xiàn)行轉(zhuǎn)列,參考如下代碼:
SELECT userid, SUM(CASE `subject` WHEN '語(yǔ)文' THEN score ELSE 0 END) as '語(yǔ)文', SUM(CASE `subject` WHEN '數(shù)學(xué)' THEN score ELSE 0 END) as '數(shù)學(xué)', SUM(CASE `subject` WHEN '英語(yǔ)' THEN score ELSE 0 END) as '英語(yǔ)', SUM(CASE `subject` WHEN '政治' THEN score ELSE 0 END) as '政治' FROM tb_score GROUP BY userid
注意,SUM() 是為了能夠使用GROUP BY根據(jù)userid進(jìn)行分組,因?yàn)槊恳粋€(gè)userid對(duì)應(yīng)的
subject="語(yǔ)文"的記錄只有一條,所以SUM() 的值就等于對(duì)應(yīng)那一條記錄的score的值。假如userid ='001' and subject='語(yǔ)文' 的記錄有兩條,則此時(shí)SUM() 的值將會(huì)是這兩條記錄的和,同理,使用Max()的值將會(huì)是這兩條記錄里面值最大的一個(gè)。但是正常情況下,一個(gè)user對(duì)應(yīng)一個(gè)subject只有一個(gè)分?jǐn)?shù),因此可以使用SUM()、MAX()、MIN()、AVG()等聚合函數(shù)都可以達(dá)到行轉(zhuǎn)列的效果。
2. 使用 IF() 函數(shù)實(shí)現(xiàn)行轉(zhuǎn)列,參考如下代碼:
SELECT userid, SUM(IF(`subject`='語(yǔ)文',score,0)) as '語(yǔ)文', SUM(IF(`subject`='數(shù)學(xué)',score,0)) as '數(shù)學(xué)', SUM(IF(`subject`='英語(yǔ)',score,0)) as '英語(yǔ)', SUM(IF(`subject`='政治',score,0)) as '政治' FROM tb_score GROUP BY userid
注意, IF(subject='語(yǔ)文',score,0) 作為條件,即對(duì)所有subject='語(yǔ)文’的記錄的score字段進(jìn)行SUM()、MAX()、MIN()、AVG()操作,如果score沒(méi)有值則默認(rèn)為0。
補(bǔ)充:列轉(zhuǎn)行:union
列轉(zhuǎn)行是上述過(guò)程的逆過(guò)程,所以其思路也比較直觀:
- 行記錄由一行變?yōu)槎嘈?,列字段由多列變?yōu)閱瘟校?/li>
- 一行變多行需要復(fù)制,列字段由多列變單列相當(dāng)于是堆積的過(guò)程,其實(shí)也可以看做是復(fù)制;
- 一行變多行,那么復(fù)制的最直觀實(shí)現(xiàn)當(dāng)然是使用union,即分別針對(duì)每門課程提取一張衍生表,最后將所有課程的衍生表union到一起即可,其中需要注意字段的對(duì)齊
按照這一思路,給出SQL實(shí)現(xiàn)如下:
SELECT uid, sum(if(course='語(yǔ)文', score, NULL)) as `語(yǔ)文`, sum(if(course='數(shù)學(xué)', score, NULL)) as `數(shù)學(xué)`, sum(if(course='英語(yǔ)', score, NULL)) as `英語(yǔ)`, sum(if(course='物理', score, NULL)) as `物理`, sum(if(course='化學(xué)', score, NULL)) as `化學(xué)`FROM scoreLongGROUP BY uid
查詢結(jié)果當(dāng)然是預(yù)期的長(zhǎng)表。這里重點(diǎn)解釋其中的三個(gè)細(xì)節(jié):
在每個(gè)單門課的衍生表中,例如這句:SELECT uid, ‘語(yǔ)文’ as course, 語(yǔ)文 as score,用單引號(hào)包裹起來(lái)的課程名稱是字符串常量,比如語(yǔ)文課的衍生表中的課程名都叫語(yǔ)文,然后將該列命名為course;第二個(gè)用反引號(hào)包裹起來(lái)的課程名實(shí)際上是從寬表中引用這一列的取值,然后將其命名為score。
這實(shí)際上對(duì)應(yīng)的一個(gè)知識(shí)點(diǎn)是:在SQL中字符串的引用用單引號(hào)(其實(shí)雙引號(hào)也可以),而列字段名稱的引用則是用反引號(hào).
上述用到了where條件過(guò)濾成績(jī)?yōu)榭罩档挠涗洠@實(shí)際是由于在原表中存在有空值的情況,如不加以過(guò)濾則在本例中最終查詢記錄有10條,其中兩條記錄的成績(jī)字段為空
最后,本例中用union關(guān)鍵字實(shí)現(xiàn)了多表的縱向拼接,實(shí)際上用union all更為合理,二者的區(qū)別是union會(huì)完成記錄去重;而union all則簡(jiǎn)單的拼接,在確定不存在重復(fù)或無(wú)需去重的情況下其效率更高。
總結(jié)
到此這篇關(guān)于SQL中如何將行轉(zhuǎn)成列的文章就介紹到這了,更多相關(guān)SQL將行轉(zhuǎn)成列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mysql 行轉(zhuǎn)列和列轉(zhuǎn)行實(shí)例詳解
- sql語(yǔ)句實(shí)現(xiàn)行轉(zhuǎn)列的3種方法實(shí)例
- SQL行轉(zhuǎn)列、列轉(zhuǎn)行的簡(jiǎn)單實(shí)現(xiàn)
- mysql 列轉(zhuǎn)行,合并字段的方法(必看)
- 數(shù)據(jù)庫(kù)實(shí)現(xiàn)行列轉(zhuǎn)換(mysql示例)
- MySQL存儲(chǔ)過(guò)程中使用動(dòng)態(tài)行轉(zhuǎn)列
- 一個(gè)簡(jiǎn)單的SQL 行列轉(zhuǎn)換語(yǔ)句
- 深入SQL中PIVOT 行列轉(zhuǎn)換詳解
- MySQL 中行轉(zhuǎn)列的方法
- MySQL中將一列以逗號(hào)分隔的值行轉(zhuǎn)列的實(shí)現(xiàn)
相關(guān)文章
Mysql 5.6.37 winx64安裝雙版本mysql筆記記錄
機(jī)器上現(xiàn)在已經(jīng)存在5.0版本MySQL的情況下裝一個(gè)最新版的mysql,下文通過(guò)實(shí)例代碼給大家介紹Mysql 5.6.37 winx64安裝雙版本mysql筆記記錄,感興趣的朋友一起看看吧2017-07-07
MySQL中DATE_FORMAT()函數(shù)的具體使用
本文主要介紹了MySQL中DATE_FORMAT()函數(shù)的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
mysql中varchar類型的日期進(jìn)行比較、排序等操作的實(shí)現(xiàn)
在mysql使用過(guò)程中,日期一般都是以datetime、timestamp等格式進(jìn)行存儲(chǔ)的,但有時(shí)會(huì)因?yàn)樘厥獾男枨蠡驓v史原因,日期的存儲(chǔ)格式是varchar,那么應(yīng)該怎么進(jìn)行比較和排序等問(wèn)題,本文就來(lái)介紹一下2021-11-11
MySQL查詢進(jìn)階操作從函數(shù)到表連接的使用
這篇文章主要介紹了MySQL查詢進(jìn)階從函數(shù)到表連接的使用,包括mysql函數(shù)的使用,MySQL的分組分頁(yè)及查詢關(guān)鍵字的執(zhí)行順序,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
安裝mysql-8.0.19-winx64遇到的問(wèn)題:Can''t create directory ''xxxx\Da
這篇文章主要介紹了安裝mysql-8.0.19-winx64遇到的坑 ,Can't create directory 'xxxx\Database\',非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02

