在做一些数据分析与数据展示时,经常会遇到行转列,列转行的需求,今天就来总结下:

在开始之前,先来创建一个临时表,并且写入一些测试数据:

/*
第一步:创建临时表结构
*/
CREATE TABLE #Student --创建临时表
(
StuName nvarchar(20), --学生名称
StuSubject nvarchar(20),--考试科目
StuScore int --考试成绩
)
DROP TABLE #Student --删除临时表
SELECT * FROM #Student --查询所有数据 /*
第二步:写入测试数据
*/
--张三
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','语文',80);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','数学',75);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','英语',65);
--李四
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','语文',36);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','数学',56);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','英语',38);
--王五
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','语文',69);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','数学',80);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','英语',78);
--赵六
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','语文',80);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','数学',80);
INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','英语',95);

数据准备好了之后,开始今天的正题:

一:行转列,下面是转换之前与之后的截图对比

 方法1:使用Case when 方式

SELECT StuSubject
,SUM(CASE WHEN StuName='张三' THEN StuScore END) as '张三'
,SUM(CASE WHEN StuName='王五' THEN StuScore END) as '王五'
,SUM(CASE WHEN StuName='赵六' THEN StuScore END) as '赵六'
FROM #Student
GROUP BY StuSubject

适用场景:要转换成多少列确定,比如上面,已经确切知道只有张三、李四、王五、赵六 四个人;

缺点:1.如果有20个人,要写20个CASE 判断,写起来恶心,代码不优雅;

           2.无法解决列是动态产生的问题,比如按月份日期转换2月有可能28天,其它月份30天;

方法2:使用PIVOT 关键字

SELECT *
FROM #Student
PIVOT(SUM(StuScore) FOR [StuName] IN("李四","王五","张三","赵六")) AS T

适用场景:要转换成多少列确定,比如上面,已经确切知道只有张三、李四、王五、赵六 四个人;

缺点:1.无法解决列是动态产生的问题,比如按月份日期转换2月有可能28天,其它月份30天;

方法3:使用PIVOT、EXEC关键

Declare @StuName varchar(100);
Declare @sql nvarchar(4000)
--步骤1.假设列不固定,是动态产生的,需要先将所有列组合成一个长字符串,比如A,B,C ,
下面的写法只能在SQL server2017中运行,更多将多行字段合并成一个字段方法参考:https://www.cnblogs.com/Rawls/p/10758788.html
SELECT @StuName='"'+STRING_AGG(StuName,'","')+'"'
FROM (
SELECT StuName from #Student GROUP BY StuName
) AS TE
--Print @StuName
--步骤2.由于动态产生的列,脚本不能执行,所以用Exec来执行,把脚本写成一个字符串。
SET @sql='
SELECT *
FROM #Student
PIVOT(SUM(StuScore) FOR [StuName] IN('+@StuName+')) AS T
'
--步骤3.执行脚本
Exec(@sql)

适用场景:可以解决列是动态产生的问题,不然这样的写法,太曲线救国了,很长一堆代码,

管你2月是28天还是100天,只要在步骤1中拼接起来就搞定了;

这一篇介绍了如何把数据行转换成数据列,下一篇介绍如果把数据列转换成数据行:https://www.cnblogs.com/Rawls/p/11027605.html

Sql server 中将数据行转列列转行(一)的更多相关文章

  1. Sql server 中将数据行转列列转行(二)

    老规矩,先弄一波测试数据,数据填充代码没有什么意义,先折叠起来: /* 第一步:创建临时表结构 */ CREATE TABLE #Student --创建临时表 ( StuName ), --学生名称 ...

  2. 在SQL Server中将数据导出为XML和Json

        有时候需要一次性将SQL Server中的数据导出给其他部门的也许进行关联或分析,这种需求对于SSIS来说当然是非常简单,但很多时候仅仅需要一次性导出这些数据而建立一个SSIS包就显得小题大做 ...

  3. SQL Server 插入数据时自增长列如何指定数值

    SQL Server 表在导入数据时,有时需要将自增长列指定数值,来保证导入前后的数据完全一致,如何实现? SQL Server 提供了方法: SET IDENTITY_INSERT,允许将显式值插入 ...

  4. SQL SERVER 实现多行转多列

    有这样一个需求,一个表单主表,一个扩展列表,查询的时候要把扩展列表中的多行转成主表多列. 比如 dt_zhubiao [主表] id type title 1 1 表单1-1 2 1 表单1-2 3 ...

  5. SQL Server中将多行数据拼接为一行数据(一个字符串)

    表A中id与表B中aid为一对多的关系 例如: 表A: id name a1 tom a2 lily a3 lucy 表B: id aid value b1 a1 B1 b2 a1 B2 b3 a2 ...

  6. SQL Server中将多行数据拼接为一行数据并且有特殊字符

    有表结构如下: 这时,要求显示所有学生的爱好的结果集,代码如下: ) as hobby FROM ( SELECT name, (SELECT hobby+',' FROM student WHERE ...

  7. 在SQL Server 2014里可更新的列存储索引 (Updateable Column Store Indexes)

    传统的关系数据库服务引擎往往并不是对超大量数据进行分析计算的最佳平台,为此,SQL Server中开发了分析服务引擎去对大笔数据进行分析计算.当然,对于数据的存放平台SQL Server数据库引擎而言 ...

  8. 通过DBCC Page查看在SQL Server中哪行数据被锁住了?

    原文:通过DBCC Page查看在SQL Server中哪行数据被锁住了? 如何查看被锁的是哪行数据?通过dbcc page可以. 要想明白这个问题: 首先,需要模拟阻塞问题,这里直接模拟了阻塞问题的 ...

  9. SQL Server获取指定行的数据

    SQL Server获取指定行(如第二行)的数据   --SQL Server获取指定行(如第二行)的数据-- --法一(对象法)-- select * from ( select * , numbe ...

随机推荐

  1. Dapper 一对多查询 one to many

    参考文档:Dapper one to many Table public class Person { public int Id { get; set; } public string Name { ...

  2. dfs 解决(隐式)图搜索问题

    132. 单词搜索 II 中文 English 给出一个由小写字母组成的矩阵和一个字典.找出所有同时在字典和矩阵中出现的单词.一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动. ...

  3. Java Mail 异常

    Java Mail 异常 java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream 解决方案: 把Jar包换一个比较高的版本就 ...

  4. 项目Beta冲刺(团队3/7)

    项目Beta冲刺(团队) --3/7 作业要求: 项目Beta冲刺(团队) 1.团队信息 团队名 :男上加男 成员信息 : 队员学号 队员姓名 个人博客地址 备注 221600427 Alicesft ...

  5. Easyui combobox 源码修改模糊查询v=1.34

    原来的匹配方式: $.fn.combobox.defaults=$.extend({},$.fn.combo.defaults,{valueField:"value",textFi ...

  6. nginx 获取源IP 获取经过N层Nginx转发的访问来源真实IP

    1. nginx 配置文件中获取源IP的配置项 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; #一般的we ...

  7. Ofbiz项目学习——阶段性小结——删除数据

    一.根据主键进行删除 /** * 按主键进行删除 * @param dctx * @param context * @return */ public static Map<String,Obj ...

  8. GeoIP简介与资源,定位经纬度,获取用户IP

    所谓GeoIP,就是通过来访者的IP,定位他的经纬度,国家/地区,省市,甚至街道等位置信息.这里面的技术不算难题,关键在于有个精准的数据库.有了准确的数据源就奇货可居赚点小钱,可是发扬合作精神,集体贡 ...

  9. 轻松学习之三——IMP指针的作用

    http://www.jianshu.com/p/425a39d43d16 可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数 ...

  10. windows使用 xxx.bat运行相关指令

    今日思语:成人的世界,请停止低层次的忙碌 一般是windows上需要执行一些支持的命令时,我们一般都会直接使用控制台去操作,对于需要频繁操作的指令来说,使用控制台略显有些不便,比如不小心关闭后控制台后 ...