Pivot 和 Unpivot
在TSQL中,使用Pivot和Unpivot运算符将一个关系表转换成另外一个关系表,两个命令实现的操作是“相反”的,但是,pivot之后,不能通过unpivot将数据还原。这两个运算符的操作数比较复杂,记录一下自己的总结,以后用到时,作为参考。
一,Pivot用法
Pivot旋转的作用,是将关系表(table_source)中的列(pivot_column)的值,转换成另一个关系表(pivot_table)的列名:
table_source
pivot
(
aggregation_function(aggregated_column)
for pivot_column in ([pivot_column_value_list])
) as pivot_table_alias
透视操作的处理流程是:
- 对pivot_column和 aggregated_column的其余column进行分组,即,group by other_columns;
- 当pivot_column值等于某一个指定值,计算aggregated_column的聚合值;
在使用透视命令时,需要注意:
- pivot将table_source旋转成透视表(pivot_table)之后,不能再被引用
- pivot_column的列值,必须使用中括号([])界定符
- 必须显式命名pivot_table的别名
1,创建示例数据
use tempdb
go drop table if exists dbo.usr
go create table dbo.usr
(
name varchar(10),
score int,
class varchar(8)
)
go insert into dbo.usr
values('a',20,'math'),('b',21,'math'),('c',22,'phy'),('d',23,'phy')
,('a',22,'phy'),('b',23,'phy'),('c',24,'math'),('d',25,'math')
go

2,对name进行分组,对score进行聚合,将class列的值转换为列名
select p.name,p.math,p.phy
from dbo.usr u
pivot
(
sum(score)
for class in([math],[phy])
) as p

3,pivot的等价写法:使用case when语句实现
pivot命令的执行流程很简单,使用caseh when子句实现pivot的功能
select u.name,
sum(case when u.class='math' then u.score else null end) as math,
sum(case when u.class='phy' then u.score else null end) as phy
from dbo.usr u
group by u.name
使用group by子句对name列分组,使用 case when 语句将pivot_column的列值作为列名返回,并对aggregated_column计算聚合值。
4,动态Pivot写法
静态pivot写法的弊端是:如果pivot_column的列值发生变化,静态pivot不能对新增的列值进行透视,变通方法是使用动态sql,拼接列值
Script1,使用case-when子句实现
declare @sql nvarchar(max)
declare @columnlist nvarchar(max) set @columnlist=N'' ;with cte as
(
select distinct class
from dbo.usr
)
select @columnlist+='sum(case when u.class='''+cast(class as varchar(10))+N''' then u.score else null end) as ['+cast(class as varchar(10))+N'],'
from cte select @columnlist=SUBSTRING(@columnlist,1,len(@columnlist)-1) select @sql=
N'select u.name,'
+@columnlist
+N'from dbo.usr u
group by u.name' exec(@sql)
Script2,使用pivot子句实现
declare @sql nvarchar(max)
declare @classlist nvarchar(max) set @classlist=N'' ;with cte as
(
select distinct class
from dbo.usr
)
select @classlist+=N'['+cast(class as varchar(11))+N'],'
from cte select @classlist=SUBSTRING(@classlist,1,len(@classlist)-1) select @sql=N'select p.name,'+@classlist+
N' from dbo.usr u
PIVOT
(
sum(score)
for class in('+@classlist+N')
) as p' exec (@sql)
二,Unpivot用法
unpivot是将列名转换为列值,列名做为列值,因此,会新增两个column:一个column用于存储列名,一个column用于存储列值
table_soucr
unpivot
(
newcolumn_store_unpivotcolumn_name for
newcolumn_store_unpivotcolumn_value in (unpivotcolumn_name_list)
)
逆透视(unpivot)的处理流程是:
- unpivotcolumn_name_list是逆透视列的列表,其列值是相兼容的,能够存储在一个column中
- 保持其他列(除unpivotcolumn_name_list之外的所有列)的列值不变
- 依次将unpivotcolumn的列名存储到newcolumn_store_unpivotcolumn_name字段中,将unpivotcolumn的列值存储到newcolumn_store_unpivotcolumn_value字段中
1,创建示例数据
CREATE TABLE dbo.Venders
(
VendorID int,
Emp1 int,
Emp2 int,
Emp3 int,
Emp4 int,
Emp5 int
);
GO INSERT INTO dbo.Venders VALUES (1,4,3,5,4,4);
INSERT INTO dbo.Venders VALUES (2,4,1,5,5,5);
INSERT INTO dbo.Venders VALUES (3,4,3,5,4,4);
INSERT INTO dbo.Venders VALUES (4,4,2,5,5,4);
INSERT INTO dbo.Venders VALUES (5,5,1,5,5,5);
GO

2,unpivot用法示例
将Emp1, Emp2, Emp3, Emp4, Emp5的列名和列值存储到字段:Employee和Orders中
SELECT VendorID, Employee, Orders
FROM dbo.Venders as p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO

3,unpivot可以使用union all来实现
select VendorID, 'Emp1' as Employee, Emp1 as Orders
from dbo.Venders
union all
select VendorID, 'Emp2' as Employee, Emp2 as Orders
from dbo.Venders
union all
select VendorID, 'Emp3' as Employee, Emp3 as Orders
from dbo.Venders
union all
select VendorID, 'Emp4' as Employee, Emp4 as Orders
from dbo.Venders
union all
select VendorID, 'Emp5' as Employee, Emp5 as Orders
from dbo.Venders
4,动态unpivot的实现,使用动态sql语句
聪明如你,很容易实现,代码就不贴了....
三,性能讨论
pivot和unpivot的性能不是很好,不要用来处理海量的数据
参考文档:
Pivot 和 Unpivot的更多相关文章
- SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例,合并列的例子
使用过SQL Server 2000的人都知道,要想实现行列转换,必须综合利用聚合函数和动态SQL,具体实现起来需要一定的技巧,而在SQL Server 2005中,使用新引进的关键字PIVOT/UN ...
- [转]使用 PIVOT 和 UNPIVOT
可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表.PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执 ...
- 使用 PIVOT 和 UNPIVOT
http://msdn.microsoft.com/zh-cn/library/ms177410%28v=SQL.90%29.aspx 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式 ...
- 通过sql做数据透视表,数据库表行列转换(pivot和Unpivot用法)(一)
在mssql中大家都知道可以使用pivot来统计数据,实现像excel的透视表功能 一.MSsqlserver中我们通常的用法 1.Sqlserver数据库测试 ---创建测试表 Create tab ...
- 使用 PIVOT 和 UNPIVOT 行转列 列转行 报表统计 函数
官方文档:http://technet.microsoft.com/zh-cn/library/ms177410(v=SQL.105).aspx 可以使用 PIVOT 和 UNPIVOT 关系运算符将 ...
- T-Sql中的pivot和unpivot
写在前面 今天休息,抽空了解下pivot和unpivot,记得老师讲行转列的时候,貌似提到过,不过他说的最多的就是“这个你们私下可以自己学,很简单的...”,简单你咋不讲呢,不吐槽他了,还是好好整理下 ...
- sql pivot、unpivot和partition by用法
原文:sql pivot.unpivot和partition by用法 演示脚本 from sys.sysobjects where name = 'Student' AND type = 'U') ...
- pivot 与 unpivot 函数是SQL05新提供的2个函数
pivot 与 unpivot 函数是SQL05新提供的2个函数 ----------------------------------------------------------------- ...
- PIVOT和UNPIVOT使用详解
一.使用PIVOT实现数据表的列转行 建表语句: DROP TABLE STUDENT; CREATE TABLE STUDENT ( 学生编号 BYTE) NULL , 姓名 BYTE) NULL ...
随机推荐
- JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
今天为大家分享一下我自己制作的浏览器滚动条,我们知道用css来自定义滚动条也是挺好的方式,css虽然能够改变chrome浏览器的滚动条样式可以自定义,css也能够改变IE浏览器滚动条的颜色.但是css ...
- [C#] C# 基础回顾 - 匿名方法
C# 基础回顾 - 匿名方法 目录 简介 匿名方法的参数使用范围 委托示例 简介 在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法. 而 C# 2.0 -- 引进了匿名方法,在 ...
- 深入理解BFC
定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(66)-MVC WebApi 用户验证 (2)
系列目录 前言: 回顾上一节,我们利用webapi简单的登录并进行了同域访问与跨域访问来获得Token,您可以跳转到上一节下载代码来一起动手. 继续上一篇的文章,我们接下来演示利用拿到的Token来访 ...
- 谈谈一些有趣的CSS题目(七)-- 消失的边界线问题
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 玩转spring boot——结合jQuery和AngularJs
在上篇的基础上 准备工作: 修改pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...
- python 3.5 成功安装 scrapy 的步骤
http://www.cnblogs.com/hhh5460/p/5814275.html
- DDD领域驱动设计 - 设计文档模板
设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...
- OpenSUSE下编译安装OpenFoam
在不是Ubuntu系统下安装OpenFoam,需要采用编译安装的方式.以下以OpenSuSE为例进行编译安装. 1 软件包准备 需要下载两个程序包: OpenFOAM-4.x-version-4.1. ...
- angularJS(6)
angularJS(6) 一:angularJs的事件. 1.ng-click指令定义了AngularJS点击事件. <div ng-app="myapp" ng-contr ...