数据库:SQLServer 实现行转列、列转行用法笔记
在許多的互聯(lián)網(wǎng)項目當(dāng)中,報表開發(fā)是整個項目當(dāng)中很重要的一個功能模塊。其中會有一些比較復(fù)雜的報表統(tǒng)計需要行轉(zhuǎn)列或者列轉(zhuǎn)行的需求。今天給大家簡單介紹一下在SQLServer當(dāng)中如何使用PIVOT、UNPIVOT內(nèi)置函數(shù)實現(xiàn)數(shù)據(jù)報表的行轉(zhuǎn)列、列轉(zhuǎn)行。有需要的朋友可以一起學(xué)習(xí)一下。
一、PIVOT、UNPIVOT用途
官方解釋:可以使用 PIVOT 和 UNPIVOT 關(guān)系運算符將表值表達(dá)式更改為另一個表。PIVOT 通過將表達(dá)式某一列中的唯一值轉(zhuǎn)換為輸出中的多個列來旋轉(zhuǎn)表值表達(dá)式,并在必要時對最終輸出中所需的任何其余列值執(zhí)行聚合。UNPIVOT 與 PIVOT 執(zhí)行相反的操作,將表值表達(dá)式的列轉(zhuǎn)換為列值。
注意:UNPIVOT運算符通過將列旋轉(zhuǎn)到行來執(zhí)行PIVOT的反向操作,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 執(zhí)行聚合,并將多個可能的行合并為輸出中的一行。UNPIVOT 不重現(xiàn)原始表值表達(dá)式的結(jié)果,因為行已被合并。另外,UNPIVOT 輸入中的 NULL 值也在輸出中消失了。如果值消失,表明在執(zhí)行 PIVOT 操作前,輸入中可能就已存在原始 NULL 值。
二、PIVOT語法格式
SELECT <非透視的列>,
????[第一個透視的列] AS <列名稱>,
????[第二個透視的列] AS <列名稱>,
????...
????[最后一個透視的列] AS <列名稱>,
FROM
????(<生成數(shù)據(jù)的 SELECT 查詢>)
????AS <源查詢的別名>
PIVOT
(
????<聚合函數(shù)>(<要聚合的列>)
FOR
[<包含要成為列標(biāo)題的值的列>]
????IN ( [第一個透視的列], [第二個透視的列],
????... [最后一個透視的列])
) AS <透視表的別名>
<可選的 ORDER BY 子句>;
三、行轉(zhuǎn)列示例說明
-- 創(chuàng)建測試表 學(xué)習(xí)成績統(tǒng)計表 CREATE TABLE ScoreStatistics (UserName NVARCHAR(20), --學(xué)生姓名SubjectName NVARCHAR(30), --科目名稱Score FLOAT, --成績 ) -- 插入測試數(shù)據(jù) INSERT INTO ScoreStatistics SELECT '小王', '語文', 100 INSERT INTO ScoreStatistics SELECT '小王', '數(shù)學(xué)', 90.5 INSERT INTO ScoreStatistics SELECT '小王', '英語', 88 INSERT INTO ScoreStatistics SELECT '小王', '歷史', 65 INSERT INTO ScoreStatistics SELECT '小李', '語文', 81 INSERT INTO ScoreStatistics SELECT '小李', '數(shù)學(xué)', 99 INSERT INTO ScoreStatistics SELECT '小李', '英語', 95 INSERT INTO ScoreStatistics SELECT '小李', '歷史', 90 INSERT INTO ScoreStatistics SELECT '小劉', '語文', 90 INSERT INTO ScoreStatistics SELECT '小劉', '數(shù)學(xué)', 85 INSERT INTO ScoreStatistics SELECT '小劉', '英語', 59 INSERT INTO ScoreStatistics SELECT '小劉', '歷史', 98 -- 傳統(tǒng)寫法 select UserName,max(case SubjectName when '語文' then Score else 0 end)語文,max(case SubjectName when '數(shù)學(xué)'then Score else 0 end)數(shù)學(xué),max(case SubjectName when '英語'then Score else 0 end)英語,max(case SubjectName when '歷史'then Score else 0 end)歷史 from ScoreStatistics group by UserName -- PIVOT 寫法更簡潔 SELECT * FROM ScoreStatistics AS P PIVOT (SUM(Score/*行轉(zhuǎn)列后 列的值*/) FORp.SubjectName/*需要行轉(zhuǎn)列的列*/ IN ([語文],[數(shù)學(xué)],[英語],歷史/*列的值*/) ) AS T -- order by 語文 desc 具體科目排序 -- order by username desc -- 姓名排序 -- 動態(tài)拼接列的示例 DECLARE @sql_str VARCHAR(8000); -- 要執(zhí)行的sql --拿到數(shù)值列 [歷史],[數(shù)學(xué)],[英語],[語文] DECLARE @sql_col VARCHAR(8000); SELECT @sql_col = ISNULL(@sql_col + ',','') + QUOTENAME(SubjectName) FROM ScoreStatistics GROUP BY SubjectName; print(@sql_col); -- 打印數(shù)值列,不必需 SET @sql_str = ' SELECT * FROM ( SELECT [UserName],[SubjectName],[Score] FROM [ScoreStatistics]) p PIVOT (SUM([Score]) FOR [SubjectName] IN ( '+ @sql_col +') ) AS pvt ORDER BY pvt.[UserName]' PRINT (@sql_str);--打印執(zhí)行的sql EXEC (@sql_str);-- 執(zhí)行查詢輸出結(jié)果:
UserName 語文 數(shù)學(xué) 英語 歷史
小王 100 90.5 88 65
小劉 90 85 59 98
小李 81 99 95 90
四、列轉(zhuǎn)行示例
-- 插入測試表CREATE TABLE ScoreSummary( UserName NVARCHAR(20), --學(xué)生姓名 數(shù)學(xué) FLOAT, --數(shù)學(xué)成績 英語 FLOAT, --英語成績 語文 FLOAT, --語文成績 歷史 FLOAT, --歷史成績)-- 插入測試數(shù)據(jù)INSERT INTO ScoreSummary SELECT '小李',81,99,95,90;INSERT INTO ScoreSummary SELECT '小劉',90,85,59,98;INSERT INTO ScoreSummary SELECT '小王',100,90.5,88,65;-- 查詢用法select aa.UserName,aa.Scorefrom (select UserName,數(shù)學(xué),英語,語文,歷史 from dbo.ScoreSummary) as aunpivot(Score for ScoreSummary in(數(shù)學(xué),英語,語文,歷史)) as aa order by aa.UserName 輸出結(jié)果:UserName Score
小李 81
小李 99
小李 95
小李 90
小劉 90
小劉 85
小劉 59
小劉 98
小王 100
小王 90.5
小王 88
小王 65
IT技術(shù)分享社區(qū)
個人博客網(wǎng)站:https://programmerblog.xyz
文章推薦 SQL常用語句大全(值得收藏) 辦公技巧:常用的100個Word快捷鍵! GitHub上值得收藏的100個精選前端項目! 數(shù)據(jù)庫優(yōu)化:SQL 查找是否"存在",別再 count 了,很耗費時間的! 學(xué)習(xí) MySQL 高性能優(yōu)化原理,這一篇就夠了! MySQL優(yōu)化:數(shù)據(jù)量很大,分頁查詢很慢,有什么優(yōu)化方案? 數(shù)據(jù)庫:MySQL中,當(dāng)update修改數(shù)據(jù)與原數(shù)據(jù)相同時會再次執(zhí)行嗎?
總結(jié)
以上是生活随笔為你收集整理的数据库:SQLServer 实现行转列、列转行用法笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Linux下群ping脚本,Linux
- 下一篇: windows批量ping脚本