SqlServer行转列

SQL Server行转列、不确定列的行转列

本文使用的方法:

1、用Case When

2、PIVOT函数

 

首先,模拟一张表:

CREATE TABLE TempSubjectResult
(
StudentName NVARCHAR(50) NOT NULL,
StudentSubject NVARCHAR(50) NOT NULL,
StudentGrade DECIMAL(4,1) NOT NULL
)
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小姚','语文','80')
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小姚','数学','70')
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小姚','英语','60')
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小明','语文','90')
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小明','数学','95')
INSERT INTO TempSubjectResult(StudentName,StudentSubject,StudentGrade) VALUES ('小明','英语','98')

SELECT * FROM TempSubjectResult

 

表数据为:

 

 

-----------------------------------------------------------------------------普通版:转置的列确定-----------------------------------------------------------------------------

 

方法一:Case When

-- 1 Case When普通版
SELECT StudentName 学生名,
       MAX(CASE WHEN StudentSubject='语文' THEN StudentGrade END) 语文,
       MAX(CASE WHEN StudentSubject='数学' THEN StudentGrade END) 数学,
       MAX(CASE WHEN StudentSubject='英语' THEN StudentGrade END) 英语
  FROM TempSubjectResult
 GROUP BY StudentName

 

方法二:PIVOT函数

SELECT * 
  FROM TempSubjectResult 
  PIVOT(MAX(StudentGrade) FOR StudentSubject IN([语文],[数学],[英语])) T

 

 

以上为知道学科有“语文、数学、英语”,如果不确定科目呢?

此时可以用动态SQL查询,请看进阶版

 

-----------------------------------------------------------------------------升级版:转置的列不确定-----------------------------------------------------------------------------

 

方法三、 Case When升级版 动态SQL

-- Case When升级版 动态SQL
DECLARE @SqlText NVARCHAR(4000)='SELECT StudentName ''学生名'', ' -- SQL头部分 SELECT
SELECT @SqlText=@SqlText+' MAX(CASE WHEN StudentSubject='''+StudentSubject+''' THEN StudentGrade END) '''+StudentSubject +''',' FROM (SELECT DISTINCT StudentSubject FROM TempSubjectResult) T -- 拼接CASE WHEN 
SELECT @SqlText= LEFT(@SqlText,LEN(@SqlText)-1)+' FROM #TempSubjectResult GROUP BY StudentName' -- 拼接 FROM后面部分
PRINT @SqlText
EXEC (@SqlText)

 

 

 

方法四、PIVOT升级版 动态SQL

 

-- PIVOT升级版 动态SQL
DECLARE @SqlSubject NVARCHAR(4000)
SELECT @SqlSubject= STUFF((SELECT '],[' + T.StudentSubject FROM (SELECT DISTINCT StudentSubject FROM TempSubjectResult) T  FOR XML PATH('')),1,2,'')+']' -- 获取PIVOT科目
DECLARE @SqlPIVOT NVARCHAR(4000)='SELECT * FROM #TempSubjectResult PIVOT(MAX(StudentGrade) FOR StudentSubject IN('+@SqlSubject+')) T' -- 拼接PIVOT
PRINT @SqlPIVOT
EXEC (@SqlPIVOT)

 

 

以下情况推荐使用动态转换:

1、需要转置的列不确定,比如转置月的天数,月份的天数有28.29.30.31天,不确定
2、需要转置的列非常多时候,不方便一个个写

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值