老生常谈之SQL Server (行转列,列转行)
Open the first article

在本文章中主要介绍以下内容:
- 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
结果:

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
结果:

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)
结果:

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 (行转列,列转行)的更多相关文章
- SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...
- SQL Server中的标识列
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server 2016:内存列存储索引
作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...
- SQL Server ->> ColumnStore Index(列存储索引)
Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...
- Sql Server中的标识列(自增长字段)
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...
- SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏
SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...
- SQL Server 行转列重温
转载自http://www.cnblogs.com/kerrycode/ 行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER ...
- 【转载】SQL Server行转列,列转行
行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...
- Sql Server 行转列
--摘自百度 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (… ...
随机推荐
- iframe 父页面与子页面之间的方法的相互调用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 通过 itms:services://? 在线安装ipa ,跨过app-store
1.需要一个html文件,引导下载用户在线安装ipa <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&quo ...
- Ecshop去掉模版中随机出现Ecshop版权的方法
EC如果是免费用户用的话,模版里面会随机出现 powered by ecshop 的字样,看了一下原来是在COMMON.JS里面写的一段代码,删除掉就可以解决掉了,方法如下: 打开 js/commo ...
- 前端程序员的蜕变——JS的 event 对象属性、使用实例、兼容性处理(极大提高代码效率、减少代码量)
下面讨论一下 js 中的 Event 对象,主要从以下三个方面详细的描述(点击标题可跳转到对应部分): 1.什么是event 2.怎么用event,用他该注意什么,几个简单实际应用 3.event在不 ...
- Web.config 自动替换值
开发项目中,有些可能会改变的值,如是否记录日志,记录日志路径等,我们都会配置在Web.config的<appSettings></appSettings>节点, 也比如数据库的 ...
- Spring Boot 集成 Mybatis
原文:https://github.com/x113773/testall/issues/9 方式一:mybatis-spring-boot-starter---这种方式比较简单,具体步骤如下:1. ...
- Linux终端类型
unix是一个多用户多任务的操作系统.早期电脑昂贵,所以当时使用便宜的设备连接到电脑上(当时还没有键盘和显示器,使用纸带和卡片来输入输出)来使用操作系统,这个便宜的设备就是终端,也可以认为终端是一种控 ...
- as 快捷键
as 快捷键 Ctrl+G / Ctrl+Alt+Shift+G:查询变量或者函数或者类在哪里被使用或被调用,后者是前者的复杂表现,可以选择查询范围等. Alt+H:查找功能,全局查找 F4:查看类 ...
- [leetcode-561-Array Partition I]
Given an array of 2n integers, your task is to group these integers into n pairs of integer,say (a1, ...
- Struts2拦截器记录系统操作日志
前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部 ...