SQL Server 2008中的Pivot和UnPivot

news/2024/7/7 20:00:00

SQL Server 2008中SQL应用系列--目录索引

 

今天给新成员讲解PIVOT 和 UNPIVOT示例,顺便整理了一下其用法。这是自SQL Server 2005起提供的新功能。

官方示例:http://msdn.microsoft.com/zh-cn/library/ms177410%28v=sql.105%29.aspx

首先看PIVOT示例:

基本表数据:

View Code
IF NOT OBJECT_ID('tb_Income') IS NULL
DROP TABLE [tb_Income]

/****** Object: Table [dbo].[tb_Income] Script Date: 2012/4/5 8:19:21 ******/


CREATE TABLE [dbo].[tb_Income](
----[PKID] int primary key identity(101,1),
[PName] [Nvarchar](20) NOT NULL,
[CYear] Smallint NOT NULL,
[CMonth] TinyInt NOT NULL,
[CMoney] Decimal (10,2) Not Null

)

GO
INSERT [dbo].[tb_Income]
SELECT '胡一刀',2011,2,5600
union ALL SELECT '胡一刀',2011,1,5678
union ALL SELECT '胡一刀',2011,3,6798
union ALL SELECT '胡一刀',2011,4,7800
union ALL SELECT '胡一刀',2011,5,8899
union ALL SELECT '胡一刀',2011,8,8877
union ALL SELECT '胡一刀',2011,6,7788
union ALL SELECT '胡一刀',2011,7,6798
union ALL SELECT '胡一刀',2011,10,10000
union ALL SELECT '胡一刀',2011,9,12021
union ALL SELECT '胡一刀',2011,11,8799
union ALL SELECT '胡一刀',2011,12,10002

union ALL SELECT '苗人凤',2011,1,3455
union ALL SELECT '苗人凤',2011,2,4567
union ALL SELECT '苗人凤',2011,3,5676
union ALL SELECT '苗人凤',2011,4,5600
union ALL SELECT '苗人凤',2011,5,6788
union ALL SELECT '苗人凤',2011,6,5679
union ALL SELECT '苗人凤',2011,7,6785
union ALL SELECT '苗人凤',2011,8,7896
union ALL SELECT '苗人凤',2011,9,7890
union ALL SELECT '苗人凤',2011,10,7799
union ALL SELECT '苗人凤',2011,11,9988

union ALL SELECT '郑希来',2011,2,5600
union ALL SELECT '郑希来',2011,3,2345
union ALL SELECT '郑希来',2011,5,12000
union ALL SELECT '郑希来',2011,4,23456
union ALL SELECT '郑希来',2011,6,4567
union ALL SELECT '郑希来',2011,7,6789
union ALL SELECT '郑希来',2011,8,9998
union ALL SELECT '郑希来',2011,9,34567
union ALL SELECT '郑希来',2011,12,5609

GO

测试结果如下:

SELECT * FROM tb_Income
GO

/*

PName CYear CMonth CMoney
胡一刀 2011 2 5600.00
胡一刀 2011 1 5678.00
胡一刀 2011 3 6798.00
胡一刀 2011 4 7800.00
胡一刀 2011 5 8899.00
胡一刀 2011 8 8877.00
胡一刀 2011 6 7788.00
胡一刀 2011 7 6798.00
胡一刀 2011 10 10000.00
胡一刀 2011 9 12021.00
胡一刀 2011 11 8799.00
胡一刀 2011 12 10002.00
苗人凤 2011 1 3455.00
苗人凤 2011 2 4567.00
苗人凤 2011 3 5676.00
苗人凤 2011 4 5600.00
苗人凤 2011 5 6788.00
苗人凤 2011 6 5679.00
苗人凤 2011 7 6785.00
苗人凤 2011 8 7896.00
苗人凤 2011 9 7890.00
苗人凤 2011 10 7799.00
苗人凤 2011 11 9988.00
郑希来 2011 2 5600.00
郑希来 2011 3 2345.00
郑希来 2011 5 12000.00
郑希来 2011 4 23456.00
郑希来 2011 6 4567.00
郑希来 2011 7 6789.00
郑希来 2011 8 9998.00
郑希来 2011 9 34567.00
郑希来 2011 12 5609.00
*/

现在需要统计2011年的个人总工资,使用Group by 即可:

SELECT PName,sum(Cmoney) as YearMoney from tb_Income
GROUP BY PName
ORDER BY sum(Cmoney) desc

/*
PName YearMoney
郑希来 104931.00
胡一刀 99060.00
苗人凤 72123.00
*/


现在我们来进行行列转换:

SELECT CYear,胡一刀,苗人凤,郑希来 FROM tb_Income 
PIVOT(sum(CMoney)
FOR PName IN
(胡一刀,苗人凤,郑希来)) t

/*
CYear 胡一刀 苗人凤 郑希来
2011 5678.00 3455.00 NULL
2011 5600.00 4567.00 5600.00
2011 6798.00 5676.00 2345.00
2011 7800.00 5600.00 23456.00
2011 8899.00 6788.00 12000.00
2011 7788.00 5679.00 4567.00
2011 6798.00 6785.00 6789.00
2011 8877.00 7896.00 9998.00
2011 12021.00 7890.00 34567.00
2011 10000.00 7799.00 NULL
2011 8799.00 9988.00 NULL
2011 10002.00 NULL 5609.00
*/

注意行列已经转换,再汇总,关键是去除干扰列,重新构建新数据集X:

SELECT 胡一刀,苗人凤,郑希来 FROM 
(SELECT PName,CMoney FROM tb_Income) X
PIVOT(sum(CMoney)
FOR PName IN
(胡一刀,苗人凤,郑希来)) t

/*
胡一刀 苗人凤 郑希来
99060.00 72123.00 104931.00
*/

 

UNPIVOT的示例更简单一些:

生成基本数据:

View Code
IF NOT OBJECT_ID('tb_Tel') IS NULL
DROP TABLE [tb_Tel]

CREATE TABLE [dbo].[tb_Tel](
----[PKID] int primary key identity(101,1),
[PName] [Nvarchar](20) NOT NULL,
[Mobile1] [Nvarchar](20) NOT NULL,
[Mobile2] [Nvarchar](20) NOT NULL,
[Mobile3] [Nvarchar](20) Not Null
)
GO
INSERT [dbo].[tb_Tel]
SELECT '胡一刀','13067894562','13567889667','16767894562'
union ALL SELECT '苗人凤','1507894562','15267889667','15367894562'
union ALL SELECT '郑希来','18067894562','18567889667','18767894562'
GO

结果:

SELECT * FROM tb_Tel

/*
PName Mobile1 Mobile2 Mobile3
胡一刀 13067894562 13567889667 16767894562
苗人凤 1507894562 15267889667 15367894562
郑希来 18067894562 18567889667 18767894562
*/

行列转换:

SELECT PName,电话类型,电话号码
FROM tb_Tel
UNPIVOT(电话类型 FOR 电话号码 IN (Mobile1,Mobile2,Mobile3) ) p

/*
PName 电话类型 电话号码
胡一刀 13067894562 Mobile1
胡一刀 13567889667 Mobile2
胡一刀 16767894562 Mobile3
苗人凤 1507894562 Mobile1
苗人凤 15267889667 Mobile2
苗人凤 15367894562 Mobile3
郑希来 18067894562 Mobile1
郑希来 18567889667 Mobile2
郑希来 18767894562 Mobile3
*/




http://lihuaxi.xjx100.cn/news/252656.html

相关文章

C语言存储类关键字

1、static这个关键字有三种用法:(1)第一种是用来修饰局部变量,使之成为静态局部变量;静态局部变量存储在数据段/bss段中,作用域是代码块作用域,生命周期是程序生命周期,链接属性是无…

BZOJ 1096: [ZJOI2007]仓库建设

传送门 斜率优化DP入门题 显然如果在一个位置 i 建一个仓库,且上一个仓库位置为 j 那么从 j1到 i 的物品显然都要存在 i 仓库是最优的 设 $f [ i ]$ 表示在第 i 个工厂建设仓库时,工厂 1 到 i 的物品都转移好的最小花费 考虑上一个仓库的位置 j 设工厂 i…

成为探路者,成就探路者!亚马逊云科技中国峰会精彩回顾

点击上方入口立即【自由构建 探索无限】一起共赴年度科技盛宴!点击阅读原文进入官方小程序观看主题演讲精彩回放前沿技术,大咖云集更多精彩不容错过

【组队学习】【28期】数据采集从入门到精通

数据采集从入门到精通 论坛版块: http://datawhale.club/c/team-learning/38-category/38 开源内容: https://github.com/datawhalechina/team-learning-program/tree/master/CollectData 学习目标 随着数字化的不断推进,数据采集在数据…

【MATLAB】矩阵运算之矩阵分解

矩阵分解:把一个矩阵分解成为矩阵连乘的形式。矩阵的分解函数cholCholesky分解cholinc稀疏矩阵的不完全Cholesky分解lu矩阵LU分解luinc稀疏矩阵的不完全LU分解qr正交三角分解svd奇异值分解gsvd一般奇异值分解schur舒尔分解 在MATLAB中线性方程组的求解主要基于四种基…

FreeBSD设备驱动管理介绍(BSP: Ti AM335x)

这段时间一直在忙FreeBSD驱动移植的项目,因此对FreeBSD做了一定的了解,鉴于网上对于FreeBSD的设备驱动资料较少,在这里给出本人对于FreeBSD驱动管理的理解心得(主要是USB驱动管理),希望能对开源开发者有所帮…

2018年终总结

转眼间,2018年就要过去了,又可以来总结一年的得失了。 今年可以说是充满了收获与挑战的一年,一年的工作基本上是围绕着node来进行的,前端相关的东西是做的越来越少。 工作相关的 今年应该说是换工位频率非常高的一年,东…

基于HTML5的Google水下搜索

这次愚人节的时候,Google推出了水下搜索,当然,这只是一个愚人的小把戏,不过效果非常不错,进入页面后,第一眼是一个水面的效果,水下的鲨鱼在游来游去,然后Google logo和搜索框从水面上…