我是firewang秩命,用技術(shù)讓數(shù)據(jù)說(shuō)話尉共,用數(shù)據(jù)讓你我進(jìn)化
本文目錄:
? PIVOT語(yǔ)法
? PIVOT示例
? UNPIVOT語(yǔ)法
? UNPIVOT示例
? PIVOT和UNPIVOT
PIVOT?通過(guò)將表達(dá)式中的一個(gè)列的唯一值轉(zhuǎn)換為輸出中的多列(即行轉(zhuǎn)列),來(lái)輪替表值表達(dá)式弃锐。PIVOT 在需要對(duì)最終輸出所需的所有剩余列值執(zhí)行聚合時(shí)運(yùn)行聚合袄友。與 PIVOT 執(zhí)行的操作相反,UNPIVOT 將表值表達(dá)式的列輪換為行(即列轉(zhuǎn)行)霹菊。
但是需要注意得是剧蚣,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 執(zhí)行聚合旋廷,并將多個(gè)可能的行合并為輸出中的一行鸠按。UNPIVOT 不重現(xiàn)原始表值表達(dá)式的結(jié)果,因?yàn)樾幸驯缓喜ⅰ?/p>
--?PIVOT?語(yǔ)法
SELECT?<非透視的列>,
????[第一個(gè)透視的列]?AS?<列名稱>,
????[第二個(gè)透視的列]?AS?<列名稱>,
????...
????[最后一個(gè)透視的列]?AS?<列名稱>,
FROM
????(<生成數(shù)據(jù)的?SELECT?查詢>)?
????AS?<源查詢的別名>
PIVOT
(
????<聚合函數(shù)>(<要聚合的列>)
FOR
[<包含要成為列標(biāo)題的值的列>]
????IN?(?[第一個(gè)透視的列],?[第二個(gè)透視的列],
????...?[最后一個(gè)透視的列])
)?AS?<透視表的別名>
<可選的?ORDER?BY?子句>;
實(shí)例的數(shù)據(jù)使用的是和?SQL筆試50題同樣的數(shù)據(jù)饶碘,?使用的平臺(tái)是SQLFIDDLE(提供在線數(shù)據(jù)庫(kù))目尖,鑒于近期全球病情的影響,各種網(wǎng)站都有一定幾率無(wú)法提供服務(wù)扎运,本次提供了SQLite數(shù)據(jù)庫(kù)瑟曲,已存入測(cè)試數(shù)據(jù)。
下載地址(13天內(nèi)有效):https://c-t.work/s/1786d12bba3e4c
--?查看每個(gè)人的年齡豪治,性別洞拨,三門課成績(jī)
select
sid,sname,sage,ssex,[語(yǔ)文],[數(shù)學(xué)],[英語(yǔ)]
from
(
select?a.sid,a.sname,a.sage,a.ssex,c.cname,b.score
??from?Student?a
??left?join?Score?b?
??on?a.sid=b.sid
??left?join?Course?c
??on?b.cid?=?c.cid
)?source_table
pivot(
??sum(score)?for
cname?in?(
??[語(yǔ)文],[數(shù)學(xué)],[英語(yǔ)]
)
?????)?t
student_pivot
將上述結(jié)果新建表 Student_pivot
create?table?Student_pivot?(
sid?varchar(10),sname?nvarchar(10),sage?datetime,ssex?nvarchar(10),?"語(yǔ)文"?int,?"數(shù)學(xué)"?int,"英語(yǔ)"?int);
insert?into?Student?values('01'?,?N'趙雷'?,?'1990-01-01'?,?N'男',?80,?90,?99);
insert?into?Student?values('02'?,?N'錢電'?,?'1990-12-21'?,?N'男',?70,?60,?80);
insert?into?Student?values('03'?,?N'孫風(fēng)'?,?'1990-05-20'?,?N'男',?80,?80,?80);
insert?into?Student?values('04'?,?N'李云'?,?'1990-08-06'?,?N'男',?50,?30,?20);
insert?into?Student?values('05'?,?N'周梅'?,?'1991-12-01'?,?N'女',?76,?87,?null);
insert?into?Student?values('06'?,?N'吳蘭'?,?'1992-03-01'?,?N'女',?31,?null,?34);
insert?into?Student?values('07'?,?N'鄭竹'?,?'1989-07-01'?,?N'女',?null,?89,?98);
insert?into?Student?values('08'?,?N'王菊'?,?'1990-01-20'?,?N'女',?null,null,null);
--?unpivot?語(yǔ)法
SELECT?[columns?not?unpivoted],
?????[unpivot_column],
???????[value_column],
FROM
(<source?query>)
AS?<alias?for?the?source?data>
UNPIVOT?(?[value_column]?FOR?[unpivot_column]?IN?(?<column_list>?)?)?
???AS?<alias?for?unpivot>
Where:
--[columns not unpivoted]:?沒(méi)有被轉(zhuǎn)換的列名。
--[unpivot_column]:?轉(zhuǎn)換的各列所匯總到的單列的名稱负拟。
--[value_column]:?轉(zhuǎn)換的各列數(shù)據(jù)所匯總到的單列的名稱烦衣。
--<source query>:?源數(shù)據(jù)。
--<alias for the source data>:?為源數(shù)據(jù)轉(zhuǎn)換后的表確定一個(gè)別名掩浙。
--<column_list>:??被轉(zhuǎn)換的列的各列的名稱花吟。
--<alias for unpivot>:?轉(zhuǎn)換操作的整個(gè)過(guò)程的別名。
然后將這張結(jié)果表里的數(shù)據(jù)UNPIVOT回去厨姚。
select?
??sid,
??sname,
??sage,
??ssex,
??subject,
??score
from?
(select?*?from?Student_pivot)?as?sp
UNPIVOT(
??score?for?subject?in?([語(yǔ)文],[數(shù)學(xué)],[英語(yǔ)])?
)?as?t
特別注意那些成績(jī)?yōu)榭盏男杏涗浂紱](méi)有出現(xiàn)衅澈!
本文項(xiàng)目地址:
https://github.com/firewang/sql50
參考網(wǎng)址:
https://docs.microsoft.com/zh-cn/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15
https://sql50.readthedocs.io/zh_CN/latest/
https://github.com/firewang/sql50