老規矩,先弄一波測試數據,數據填充代碼沒有什么意義,先折疊起來:

/* 第一步:創建臨時表結構 */ CREATE TABLE #Student --創建臨時表 ( StuName nvarchar(20), --學生名稱 Chinese int, Math int, English int ) DROP TABLE #Student --刪除臨時表 SELECT * FROM #Student --查詢所有數據 INSERT INTO #Student(StuName,Chinese,Math,English) VALUES('張三',70,86,96); INSERT INTO #Student(StuName,Chinese,Math,English) VALUES('李四',49,85,86); INSERT INTO #Student(StuName,Chinese,Math,English) VALUES('王五',59,58,90); INSERT INTO #Student(StuName,Chinese,Math,English) VALUES('趙六',68,79,80);
一:列轉行,下面是轉換之前與之后的截圖對比
如果想要行轉列,參考上一篇:Sql server 中將數據行轉列列轉行(一)
方法一:使用 UNION ALL 拼接多個結果集
SELECT * FROM ( SELECT StuName,課程='語文',分數=Chinese FROM #Student UNION ALL SELECT StuName,課程='數學',分數=Math FROM #Student UNION ALL SELECT StuName,課程='英語',分數=English FROM #Student )AS TE ORDER BY TE.StuName ASC
方法二:使用UNPIVOT,推薦此方法;
SELECT * FROM #Student UNPIVOT (分數 FOR 課程 IN([Chinese],Math,English)) T
方法三:使用UNPIVOT,處理動態列情況,看過我上一篇內容的,應該知道,在進行行轉列的時候,有時候不太確定到底有多少行的可能,
會有動態的情況,但是在處理列轉行的情況時,一般每個數據庫在進行數據存儲的時候,列有多少個,都是已經確定的,不存在不確定性,
所以,第三種方法知道就可以了,實用性不大,不推薦此方法。
DECLARE @sql NVARCHAR(4000) SELECT @sql=isnull(@sql+',','')+quotename(Name) FROM syscolumns WHERE ID=object_id('Student') AND Name NOT IN('StuName') --不顯示學生名稱列 ORDER BY Colid --print @sql SET @sql=' SELECT * FROM #Student UNPIVOT (分數 FOR 課程 IN('+@sql+')) T ' Exec(@sql)
注意:上面的這一部分,由於查詢了syscolumns 數據庫內置系統表,我演示的數據是臨時表,是查不到任何數據的,必須創建實際的數據庫表才可以使用。