博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sqlserver 行转列、字符串行转列、自动生产行转列脚本
阅读量:6947 次
发布时间:2019-06-27

本文共 2878 字,大约阅读时间需要 9 分钟。

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

1、生成测试数据:

CREATE TABLE human(    name NVARCHAR(5),    --姓名    norm NVARCHAR(5),    --指标    score INT ,            --分数    grade NVARCHAR(2)    --等级)GOINSERT 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')

查询数据:

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

 

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

SELECT     name,    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 技术FROM dbo.humanGROUP BY name

结果:

 

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

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

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

SELECT  name ,        ( SELECT    grade + ''          FROM      dbo.human          WHERE     name = a.name                    AND norm = '考勤'        FOR          XML PATH('')        ) AS 考勤 ,        ( SELECT    grade + ''          FROM      dbo.human          WHERE     name = a.name                    AND norm = '生产'        FOR          XML PATH('')        ) AS 生产 ,        ( SELECT    grade + ''          FROM      dbo.human          WHERE     name = a.name                    AND norm = '技术'        FOR          XML PATH('')        ) AS 技术FROM    dbo.human aGROUP BY name;

结果:

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

SELECT  name ,        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 技术FROM    dbo.human aGROUP BY name;

结果:

 

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 DISTINCT                    norm          FROM      dbo.human        ) a; SELECT  @sql = SUBSTRING(@sql, 1, LEN(@sql) - 3);SELECT  @sql = @sql + 'FROM    dbo.human aGROUP BY name;';SELECT  @sql;EXEC (@sql);

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

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

 

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

SELECT  *FROM    ( SELECT    name ,                    norm ,                    score          FROM      dbo.human        ) t PIVOT( SUM(score) FOR norm IN ( 考勤, 生产, 技术 ) ) AS pvt;

结果:

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

SELECT  *FROM    ( SELECT    name ,                    norm ,                    grade          FROM      dbo.human        ) t PIVOT( MAX(grade) FOR norm IN ( 考勤, 生产, 技术 ) ) AS pvt;

 

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

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

 

posted on
2018-12-06 22:58 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/hiwuchong/p/10080215.html

你可能感兴趣的文章
docker 17.09.0-ce 启动更换网络地址
查看>>
关于《大道至简》第六章的收获
查看>>
JavaWeb部分面试题
查看>>
mac osx 系统开发php 的一些工具
查看>>
Tcp的三次握手,以及原理详解
查看>>
sprintboot 中占位符及多环境配置
查看>>
Oracle资源
查看>>
你需要一点点CIL
查看>>
Java中的位运算
查看>>
java连接mysql的一个小例子
查看>>
laravel queue 修改之后不生效的坑
查看>>
[USACO07JAN]Balanced Lineup
查看>>
[入门OJ3876]怎样学习哲学
查看>>
陶哲軒實分析 習題3.6.9
查看>>
Python国内豆瓣源
查看>>
html页面的局部刷新
查看>>
C#不常见的语法
查看>>
[摘录]高效人士七习惯—以终为始原则
查看>>
Office Visio简介
查看>>
[摘录]第4章 不道德的谈判策略
查看>>