老生常谈之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 (… ...
随机推荐
- phantomjs-prebuilt@2.1.14 install: `node install.js`
在用vue-cli构建项目时,npm install 安装包的时候报错了. 错误信息: npm ERR! Failed at the phantomjs-prebuilt@2.1.14 install ...
- Java基础——封装
最近学习Java面向对象方面的知识点,一直没时间更新博客,因为这块的知识点真的蛮绕的.一个知识点一个知识点的往外冒,而且对于我这个初学者来说区分构造器和方法就花费了一整天的时间.现在准备再重新过一遍知 ...
- Java使用条件语句和循环结构确定控制流
与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流.本文将简单讲解条件.循环和switch. 一.块作用域 块(block),即复合语句.是指由一对大括号括起来的若干条简单的Java语句 ...
- oracle表的简单操作
版权声明:本文为博主原创文章,转载时请注明原文链接. 1.创建表 ) ) not null,primary key(num)); 创建了一个两个字段的表,num和name,都设置为非空,num设为主键 ...
- 几个常用的linux命令(操作服务器时会用到)
目录 tmux 背景 安装 使用 启动一个tmux session 暂时离开当前session 回到之前的session 重命名session 创建window 创建pane ps scp 参考 tm ...
- div中内容无法自动换行问题
.l-text{ padding:.3em .5em; width:67%; height: auto; /*height:1.3em;*/ border:.1em #2294C3 solid; bo ...
- js中的数字格式变成货币类型的格式
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- AngularJs学习笔记1——总体介绍
这周末在家呆了两天,正好中午闲暇时间继续分享Angularjs相关,今天主要分享Angularjs总体介绍及数据绑定部分内容,下面直接进入主题. 1.基本概念: AngularJS是为了克服HTML在 ...
- maven配置本地仓库(从本地仓库下载jar包到.m2仓库)
Windows-->preference 把你的settings.xml存到一个地方maven指向你的settings.xmlsettings.xml里的地址是你们 ...
- servlet+jsp update修改页面的实现,整整搞了两个小时才搞定
package DAO; public class books { private int bid; private String bname; private int booksl; private ...