老生常谈之SQL Server (行转列,列转行)

时间:2021-08-24 22:43:30

Open the first article

老生常谈之SQL Server (行转列,列转行)

在本文章中主要介绍以下内容:

  • 1、静态行转列
  • 2、静态列转行
  • 3、动态行转列
  • 4、动态列转行

1、静态行转列

 --静态的行转列
--新建一个科目成绩表
--三个字段:学生名称,科目,成绩
CREATE TABLE SubjectScore
(
StuName nvarchar(20),
SubjectName nvarchar(20),
Fraction decimal(16,2)
) --插入4条数据
INSERT INTO SubjectScore
VALUES(N'孔子',N'语文',99) INSERT INTO SubjectScore
VALUES(N'孔子',N'数学',80) INSERT INTO SubjectScore
VALUES(N'诸葛',N'语文',75.5) INSERT INTO SubjectScore
VALUES(N'诸葛',N'数学',66) --行转列
SELECT StuName,
ISNULL(SUM(case SubjectName when N'语文' then isnull(Fraction,0)end),0)as N'语文',
ISNULL(SUM(case SubjectName when N'数学' then isnull(Fraction,0)end),0)as N'数学'
FROM SubjectScore
GROUP BY StuName --如果加了个英语科目怎么办?没错,代码要改
--下面我们加个英文科目
INSERT INTO SubjectScore
VALUES(N'诸葛',N'英语',66) --修改代码后行转列
SELECT StuName,
ISNULL(SUM(case SubjectName when N'语文' then isnull(Fraction,0)end),0)as N'语文',
ISNULL(SUM(case SubjectName when N'数学' then isnull(Fraction,0)end),0)as N'数学',
ISNULL(SUM(case SubjectName when N'英语' then isnull(Fraction,0)end),0)as N'英语'
FROM SubjectScore
GROUP BY StuName

  结果:

  老生常谈之SQL Server (行转列,列转行)    老生常谈之SQL Server (行转列,列转行)

2、静态列转行

 --静态列转行
--表结构:我们建几个中文的字段:学生名称,语文,数学
CREATE TABLE Demo_Stu
(
学生名称 nvarchar(20),
语文 decimal(16,2),
数学 decimal(16,2)
) --一样插入4条数据
INSERT INTO Demo_Stu
VALUES(N'孔子',88,99) INSERT INTO Demo_Stu
VALUES(N'孔子',99,69) INSERT INTO Demo_Stu
VALUES(N'诸葛',88,55) INSERT INTO Demo_Stu
VALUES(N'诸葛',77,63) --我们可以用union all 来实现,
--不了解 union all怎么用的兄弟请自行百度
select * from (
select 学生名称 as StuName,Subject=N'语文',Fraction=语文 from Demo_Stu
union all
select 学生名称 as StuName,Subject=N'数学',Fraction=数学 from Demo_Stu
)p order by StuName

  结果:

    老生常谈之SQL Server (行转列,列转行)         老生常谈之SQL Server (行转列,列转行)

3、动态行转列

--动态的行转列
--科目成绩表
--三个字段:学生名称,科目,成绩
CREATE TABLE SubjectScore
(
StuName nvarchar(20),
SubjectName nvarchar(20),
Fraction decimal(16,2)
) --插入4条数据
INSERT INTO SubjectScore
VALUES(N'孔子',N'语文',99) INSERT INTO SubjectScore
VALUES(N'孔子',N'数学',80) INSERT INTO SubjectScore
VALUES(N'诸葛',N'语文',75.5) INSERT INTO SubjectScore
VALUES(N'诸葛',N'数学',66) /*
动态行转列我们主要用到以下几个关键函数:
2.PIVOT
1.QUOTENAME
*/
DECLARE @sql_col NVARCHAR(4000)
DECLARE @sql_str NVARCHAR(4000)
/*取表中行转列的所有科目*/
SELECT @sql_col = ISNULL(@sql_col+',','')+QUOTENAME(SubjectName) FROM SubjectScore GROUP BY SubjectName
SET @sql_str = '
SELECT * FROM SubjectScore p PIVOT(
SUM([Fraction]) FOR [SubjectName] IN('+@sql_col+')
) pvt
order by StuName
'
EXEC (@sql_str) --如果加了个英语科目怎么办?代码不需要改动
--下面我们加个历史科目,再执行上面的行转列代码
INSERT INTO SubjectScore
VALUES(N'诸葛',N'历史',88) INSERT INTO SubjectScore
VALUES(N'孔子',N'历史',99)

  结果:

      老生常谈之SQL Server (行转列,列转行)

4、动态列转行

 --动态态列转行
--表结构:我们建几个中文的字段:学生名称,语文,数学
CREATE TABLE Demo_Stu
(
学生名称 nvarchar(20),
语文 decimal(16,2),
数学 decimal(16,2)
) --一样插入4条数据
INSERT INTO Demo_Stu
VALUES(N'孔子',88,99) INSERT INTO Demo_Stu
VALUES(N'孔子',99,69) INSERT INTO Demo_Stu
VALUES(N'诸葛',88,55) INSERT INTO Demo_Stu
VALUES(N'诸葛',77,63) --列传行
--列转行的方案来源于:Joe.TJ
--列转行的动态方案:UNPIVOT,sql2005及以后版本
--因为行是动态所以这里就从INFORMATION_SCHEMA.COLUMNS视图中获取列来构造行,同样也使用了XML处理。
DECLARE @SQL NVARCHAR(4000)=N'';
SET @SQL=STUFF((SELECT N','+QUOTENAME(COLUMN_NAME ) FROM INFORMATION_SCHEMA.COLUMNS
WHERE ORDINAL_POSITION>1 AND TABLE_NAME='Demo_Stu' FOR XML PATH('')),1,1,N'')
SET @SQL=N'SELECT *
from dbo.Demo_Stu
unpivot(分数 for 科目 in('+@SQL+'))as up';
EXEC SP_EXECUTESQL @SQL;

  总结:

      无论是静态的行转列或列转行都是会增加代码的维护性。

      建议使用动态的行转列和列转行,可减少代码的维护性,多留一手也是比较好的。

老生常谈之SQL Server (行转列,列转行)的更多相关文章

  1. SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维*,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...

  2. SQL Server中的标识列

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...

  3. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

  4. SQL Server ->> ColumnStore Index(列存储索引)

    Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...

  5. Sql Server中的标识列(自增长字段)

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...

  6. SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维*,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...

  7. SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏

    SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...

  8. SQL Server 行转列重温

    转载自http://www.cnblogs.com/kerrycode/ 行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER ...

  9. 【转载】SQL Server行转列,列转行

    行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...

  10. Sql Server 行转列

    --摘自百度 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (… ...

随机推荐

  1. DOM-Element类型

    Element类型 Element类型用于表现XML或HTML元素,提供了对元素标签名.子节点及特性的访问.Element节点具有以下特征: nodeType的值为1 nodeName的值为元素的标签 ...

  2. PJAX初体验(主要是利用HTML5 新增API pushState和replaceState+AJAX)

    说在前面 什么是PJAX呢? 站在应用角度的就是既实现了页面无刷新的效果,同时也产生了浏览器的前进和后退,而且url也会变化. 也不是什么新鲜技术,主要是AJAX+html5 pushState和re ...

  3. Talk about VR

    Virtual reality --VR ,虚拟现实,是利用计算机模拟一个三维空间的世界,提供用户关于各种感官的模拟,让用户感觉身临其境,可以及时,没有限制地观察三维空间内的事物,用户进行位置移动时, ...

  4. HDU 2602 Bone Collector --01背包

    这种01背包的裸题,本来是不想写解题报告的.但是鉴于还没写过背包的解题报告.于是来一发. 这个真的是裸的01背包. 代码: #include <iostream> #include &lt ...

  5. NDK&lpar;13&rpar;JNIEnv和JavaVM

    转自:  http://www.cnblogs.com/canphp/archive/2012/11/13/2768937.html JNIEnv是一个与线程相关的变量,不同线程的JNIEnv彼此独立 ...

  6. 2013 ACM&sol;ICPC 长沙现场赛 A题 - Alice&&num;39&semi;s Print Service (ZOJ 3726)

    Alice's Print Service Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is providing print ser ...

  7. Java写一个简单学生管理系统

    其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来 ...

  8. make clean与make distclean的区别

    make clean仅仅是清除之前编译的可执行文件及配置文件. 而make distclean要清除所有生成的文件. Makefile 在符合GNU Makefiel惯例的Makefile中,包含了一 ...

  9. 解决Postman发送post数据但是Node&period;js中req&period;body接收不到数据的问题&lbrack;已解决&rsqb;

    之前编写后台接口,测试数据都是使用的Postman,相当的方便,之前也一直使用get方法,编写Node.js一直没有问题,但是由于要编写一个注册/登陆的功能,所以发送的post数据,后台的逻辑已经编写 ...

  10. c&num; 错误 两个输出文件名解析为同一个输出路径

    检查同项目的其他文件夹下面已有其他同名窗体,影响设计器