sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本

行转列,老生常谈的问题。这里总结一下网上的方法。

1、生成测试数据:

CREATE TABLEhuman(

nameNVARCHAR(5), --姓名

norm NVARCHAR(5), --指标

score INT , --分数

grade NVARCHAR(2) --等级

)GO

INSERT INTO human(name,norm,score,grade)VALUES('旺仔','考勤',56,'c'),

('旺仔','生产',85,'b'),

('旺仔','技术',95,'a'),

('小杰','考勤',66,'a'),

('小杰','生产',77,'b'),

('小杰','技术',88,'c'),

('玉红','考勤',92,'j'),

('玉红','生产',73,'k'),

('玉红','技术',81,'m')

查询数据:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第1张图片

注意:这里的score是数值类型列,而grade是字符串类型的列

2、利用case when 语句完成行转列,其中行转列之后的列的属性是数值类型

SELECTname,SUM(CASE WHEN norm = '考勤' THEN score ELSE 0 END) AS考勤,SUM(CASE WHEN norm = '生产' THEN score ELSE 0 END) AS生产,SUM(CASE WHEN norm = '技术' THEN score ELSE 0 END) AS技术FROMdbo.humanGROUP BY name

结果:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第2张图片

3、利用case when 语句完成行转列,其中行转列之后的列的属性是字符串类型

又分为两种情况,a:是借用for xml path 拼接字符串,b:巧妙的借用max()函数可以对字符串进行运算的特点进行筛选

a:借用for xml path 拼接字符串

SELECTname ,

(SELECT grade + ''

FROMdbo.humanWHERE name =a.nameAND norm = '考勤'

FORXML PATH('')

)AS考勤 ,

(SELECT grade + ''

FROMdbo.humanWHERE name =a.nameAND norm = '生产'

FORXML PATH('')

)AS生产 ,

(SELECT grade + ''

FROMdbo.humanWHERE name =a.nameAND norm = '技术'

FORXML PATH('')

)AS技术FROMdbo.human aGROUP BY name;

结果:

6af810916d087f12925ed15286861bcd.png

b:巧妙的借用max()(或min())函数可以对字符串进行运算的特点进行筛选

SELECTname ,MAX( CASE WHEN a.norm = '考勤' THEN a.grade ELSE '' END ) AS考勤,MAX( CASE WHEN a.norm = '生产' THEN a.grade ELSE '' END ) AS生产,MAX( CASE WHEN a.norm = '技术' THEN a.grade ELSE '' END ) AS技术FROMdbo.human aGROUP BY name;

结果:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第3张图片

3、实际生产过程中会碰到这种情况:norm列的值有很多种情况,比如几十、上百个,难道我们一一手写吗?不,我们可以考虑使用拼接字符串的方式,动态实现行转列

DECLARE @sql NVARCHAR(MAX);SELECT @sql = 'select name,';SELECT @sql = @sql + 'max(case when a.norm =''' +a.norm+ '''then a.grade ELSE''''END' + ') as' + QUOTENAME(a.norm) + ','

FROM ( SELECT DISTINCTnormFROMdbo.human

) a;SELECT @sql = SUBSTRING(@sql, 1, LEN(@sql) - 3);SELECT @sql = @sql + 'FROM dbo.human a

GROUP BY name;';SELECT @sql;EXEC (@sql);

首先观察一下我们自动拼接出来的sql语句:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第4张图片

完美!拼接的语句正式我们所希望的,所以结果也不出所料:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第5张图片

4、pivot新特性实现行转列,针对行转列后,列的属性是数值类型的情况,这里指score

SELECT *

FROM ( SELECTname ,

norm ,

scoreFROMdbo.human

) t PIVOT(SUM(score) FOR norm IN ( 考勤, 生产, 技术 ) ) AS pvt;

结果:

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第6张图片

5、pivot新特性实现行转列,针对行转列后,列的属性是字符串类型的情况,这里指score

SELECT *

FROM ( SELECTname ,

norm ,

gradeFROMdbo.human

) t PIVOT(MAX(grade) FOR norm IN ( 考勤, 生产, 技术 ) ) AS pvt;

sqlserver sql行专列_sqlserver 行转列、字符串行转列、自动生产行转列脚本_第7张图片

6、同理,我们也可以通过拼接字符串的形式来组织pivot语句生成自动行转列的脚本。好动手的童鞋赶快动起来吧。

如果您有疑问,欢迎评论区交流讨论

你可能感兴趣的:(sqlserver,sql行专列)