在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

透视操作的处理流程是:

  1. 对pivot_column和 aggregated_column的其余column进行分组,即,group by other_columns;
  2. 当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)的处理流程是:

  1. unpivotcolumn_name_list是逆透视列的列表,其列值是相兼容的,能够存储在一个column中
  2. 保持其他列(除unpivotcolumn_name_list之外的所有列)的列值不变
  3. 依次将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的性能不是很好,不要用来处理海量的数据

参考文档:

Using PIVOT and UNPIVOT

Pivot 和 Unpivot的更多相关文章

  1. SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例,合并列的例子

    使用过SQL Server 2000的人都知道,要想实现行列转换,必须综合利用聚合函数和动态SQL,具体实现起来需要一定的技巧,而在SQL Server 2005中,使用新引进的关键字PIVOT/UN ...

  2. [转]使用 PIVOT 和 UNPIVOT

    可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表.PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执 ...

  3. 使用 PIVOT 和 UNPIVOT

    http://msdn.microsoft.com/zh-cn/library/ms177410%28v=SQL.90%29.aspx 可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式 ...

  4. 通过sql做数据透视表,数据库表行列转换(pivot和Unpivot用法)(一)

    在mssql中大家都知道可以使用pivot来统计数据,实现像excel的透视表功能 一.MSsqlserver中我们通常的用法 1.Sqlserver数据库测试 ---创建测试表 Create tab ...

  5. 使用 PIVOT 和 UNPIVOT 行转列 列转行 报表统计 函数

    官方文档:http://technet.microsoft.com/zh-cn/library/ms177410(v=SQL.105).aspx 可以使用 PIVOT 和 UNPIVOT 关系运算符将 ...

  6. T-Sql中的pivot和unpivot

    写在前面 今天休息,抽空了解下pivot和unpivot,记得老师讲行转列的时候,貌似提到过,不过他说的最多的就是“这个你们私下可以自己学,很简单的...”,简单你咋不讲呢,不吐槽他了,还是好好整理下 ...

  7. sql pivot、unpivot和partition by用法

    原文:sql pivot.unpivot和partition by用法 演示脚本 from sys.sysobjects where name = 'Student' AND type = 'U') ...

  8. pivot 与 unpivot 函数是SQL05新提供的2个函数

    pivot 与 unpivot 函数是SQL05新提供的2个函数   ----------------------------------------------------------------- ...

  9. PIVOT和UNPIVOT使用详解

    一.使用PIVOT实现数据表的列转行 建表语句: DROP TABLE STUDENT; CREATE TABLE STUDENT ( 学生编号 BYTE) NULL , 姓名 BYTE) NULL ...

随机推荐

  1. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  2. css3中perspective

    perspective 属性定义 3D 元素距视图的距离,以像素计.该属性允许改变 3D 元素查看 3D 元素的视图.当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本 ...

  3. 【初学python】使用python连接mysql数据查询结果并显示

    因为测试工作经常需要与后台数据库进行数据比较和统计,所以采用python编写连接数据库脚本方便测试,提高工作效率,脚本如下(python连接mysql需要引入第三方库MySQLdb,百度下载安装) # ...

  4. JavaScript正则表达式,你真的知道?

    一.前言 粗浅的编写正则表达式,是造成性能瓶颈的主要原因.如下: var reg1 = /(A+A+)+B/; var reg2 = /AA+B/; 上述两个正则表达式,匹配效果是一样的,但是,效率就 ...

  5. 从netty-example分析Netty组件续

    上文我们从netty-example的Discard服务器端示例分析了netty的组件,今天我们从另一个简单的示例Echo客户端分析一下上个示例中没有出现的netty组件. 1. 服务端的连接处理,读 ...

  6. 【NLP】前戏:一起走进条件随机场(一)

    前戏:一起走进条件随机场 作者:白宁超 2016年8月2日13:59:46 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有 ...

  7. 极光推送和友盟推送,ios端和安卓端的后端调试设置

    我是最后端的,这两天搞了一个app项目,前端安卓使用友盟很方便,调试比较顺利,然后ios就遇到各种问题了,证书.发送成功推送不成功,测试时用的TestMode(),ios上架之后就必须用product ...

  8. SAP自定义权限对象

    SAP系统自带了很多的权限对象,每一个运行画面都有非常多的权限用到.不过标准的权限对象并不一定适合于用在客户自己开发的程序里面,所以每个ABAPer都应该会自己开发一套权限对象,并引用在程序代码里面. ...

  9. [Android]使用Dagger 2来构建UserScope(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6237731.html 使用Dagger 2来构建UserSco ...

  10. 信息安全-1:python之playfair密码算法详解[原创]

    转发注明出处: http://www.cnblogs.com/0zcl/p/6105825.html 一.基本概念 古典密码是基于字符替换的密码.加密技术有:Caesar(恺撒)密码.Vigenere ...