在制作报表的时候,有时候会碰到基础资料是依照时间区间去一笔一笔记录的资料,但是使用者在看报表的时候想要将时间区间以横向的方式呈现不是直向的情况出现,又或者基础资料的表数据结构是横向的而使用者在看报表的时候想以直向方式呈现。这个时候我们就可以采用表旋转技术。所谓的表旋转,就是将表的行转换为列,或是将表的列转换为行.表旋转在某些方面也是解决了表的数据存储和实际需要之间的矛盾。

针对表旋转技术从SQL Server2005开始 系统提供两个新的关键字 PIVOT UNPIVOT可用来作表旋转操作.因为这是从SQL Server2005开始提供的新关键字,所以如果希望使用此功能需要将数据库的兼容级别设置为90

 

PIVOT用于将列值旋转为列名(即行转列)、UNPIVOT用于将列明转为列值(即列转行)


PIVOT
语法规则

第一部分 SELECT .... FROM 之間:

<non-pivoted column> : 非旋转列。

[first pivoted column] AS <column name> :旋转列 AS <列名>

[first pivoted column] 的名称将会对应与之後第三部分的 FOR column IN 里面的的名称。

第二部分 FROM ..... PIVOT 之間:

(<SELECT query that produces the data>) AS <alias for the source query> : 這裡也就是你的资料来源的地方,要注意的是尾巴AS命名的名称不可以漏掉一定要命名。

第三部分 PIVOT 跟 FOR:

<aggregation function>(<column being aggregated>) :

<聚合函数>(<被聚合的列>)。

[<column that contains the values that will become column headers>] : [<包含将被转换为列标头的值的列>]

IN ( [first pivoted column], [second pivoted column], ... [last pivoted column]) : 这部分前面有提到,这边的列名称对应的是第一部分的名称

UNPIVOT语法规则:

第一部分 SELECT .... FROM 之間:

<non-pivoted Rows> : 非旋转行。

[colgroup_column name] :列集合的列名 称将会对应与之後第三部分的 FOR column IN 里面的的名称而该列中的数据为IN后面的列名

[value set_column name]值集合的列名的名称将会对应与之後第三部分的 FOR 之前的的名称,值集合数据是根据列分组组成集合!

第二部分 FROM ..... UNPIVOT 之間:

Table Source:表源

第三部分 UNPIVOT 跟 FOR:

[value set_column name] 值集合的列名这部分前面有提到,这边的数据来源为根据[colgroup_column name]根据对应列名分组的数据

[colgroup_column name] 列集合的列名这部分前面有提到,这边的数据来源为根据 IN关键字从Table Source表数据源中获取的列的名称

IN ( [first pivoted column], [second pivoted column], ... [last pivoted column]) :这边的列名称对应的是Table Source中列的名称也是

典型实例

一、     行转列

建立一个产品销售表,内容包括员工姓名、销售日期、销售金额

代码如下:

Create table Orders

(Staff_name  char(20) not null,

OrderDate  char(50)not null,

Amount    money  notnull

)

insert into Orders values('张三','Jan',150.00)

insert into Orders values('张三','Feb',100.00)

insert into Orders values('张三','Mar',100.00)

insert into Orders values('张三','Apr',150.00)

insert into Orders values('张三','May',100.00)

insert into Orders values('张三','Jun',170.00)

insert into Orders values('张三','Jul',100.00)

insert into Orders values('张三','Aug',110.00)

insert into Orders values('张三','Sep',100.00)

insert into Orders values('张三','Oct',180.00)

insert into Orders values('张三','Now',100.00)

insert into Orders values('张三','Dec',100.00)

select Staff_name,[Jan],[Feb],[Mar],[Apr] ,[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Now],[Dec]

from(select Staff_name,OrderDate,Amount from orders) ct

pivot

(

sum(Amount)

for OrderDate in( [Jan],[Feb],[Mar],[Apr] ,[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Now],[Dec])

)as Pvt

order by Staff_name

注:使用pivot把一列拆成几列时 需要后面as取个别名 这是固定的格式 同时如 for前是必须使用聚合函数的

当然不使用pivot函数也可以得到相同效果 只是代码长切效率低但容易理解

代码如下:

select Staff_name,

sum(case when OrderDate=’Jan’ THEN Amount END) as [Jan],

sum(case when OrderDate=’Feb’ THEN Amount END) as [Feb],

sum(case when OrderDate=’Mar’ THEN Amount END) as [Mar],

sum(case when OrderDate=’Apr’ THEN Amount END) as [Jan],

sum(case when OrderDate=’May’ THEN Amount END) as [May],

sum(case when OrderDate=’Jun’ THEN Amount END) as [Jun],

sum(case when OrderDate=’Jul’ THEN Amount END) as [Jul],

sum(case when OrderDate=’Aug’ THEN Amount END) as [Aug],

sum(case when OrderDate=’Sep’ THEN Amount END) as [Sep],

sum(case when OrderDate=’Oct’ THEN Amount END) as [Oct],

sum(case when OrderDate=’Now’ THEN Amount END) as [Now],

sum(case when OrderDate=’Dec’ THEN Amount END) as [Dec]
from orders as a
group by Staff_name

转换后结果:

二、    列转行

沿用上面已经转换好的表结构,其效果如下:

代码如下:

select Staff_name ,OrderDate,Amount from orders2
unpivot
(
Amount for OrderDate in( [Jan],[Feb],[Mar],[Apr] ,[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Now],[Dec]) )as UnPvt

注:同样需要使用as取别名同样是固定的格式 unpivot函数中没有聚合函数 OrderDate和Amount列都是原来没有的 Amount列由原来的[Jan],[Feb],[Mar],[Apr] ,[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Now],[Dec])列组成

请注意,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 会执行一次聚合,从而将多个可能的行合并为输出中的单个行。而 UNPIVOT 不会重现原始表值表达式的结果,因为行已经被合并了。另外,UNPIVOT 的输入中的 NULL 不会显示在输出中,然而在执行 PIVOT 操作之前输入中可能会含有原始的 NULL 值。

同样的不使用unpivot也可以实现以上的功能

代码如下:

select Staff_name, 'Jan' as OrderDate,Jan as Amount from orders

union all

select Staff_name, 'Feb' as OrderDate,Feb as Amount from orders

union all

select Staff_name, 'Mar' as OrderDate,Mar as Amount from orders

union all

select Staff_name, 'Apr' as OrderDate,Apr as Amount from orders

union all

select Staff_name, 'May' as OrderDate,May as Amount from orders

union all

select Staff_name, 'Jun' as OrderDate,Jun as Amount from orders

union all

select Staff_name, 'Jul' as OrderDate ,Jul as Amount from orders

union all

select Staff_name, 'Aug' as OrderDate,Aug as Amount from orders

union all

select Staff_name, 'Sep' as OrderDate,Sep as Amount from orders

union all

select Staff_name, 'Oct' as OrderDate ,Oct as Amount from orders

union all

select Staff_name, 'Now' as OrderDate ,Now as Amount from orders

union all

select Staff_name, 'Dec' as OrderDate ,Dec as Amount from orders

转换后结果

通过上面示例大家可以看的出来,行转列其实就是将表中的一行拆成几列,而列转行则是将表中的多个列组成一行

SQL表旋转的更多相关文章

  1. 瑞丽的SQL-SQL Server的表旋转(行列转换)

    所谓表旋转,就是将表的行转换为列,或是将表的列转换为行,这是从SQL Server 2005開始提供的新技术.因此,如果希望使用此功能,须要将数据库的兼容级别设置为90.表旋转在某些方面也是攻克了表的 ...

  2. sql表和字段的别名

    1. sql表和字段的别名通过关键字 AS 来指定. 2.通常,定义字段别名的 AS 关键字可以省略,但我们建议不要省略 AS 关键字.别名(alias)是 SQL 的标准语法,几乎所有的数据库系统都 ...

  3. SQL表连接查询(inner join、full join、left join、right join)

    SQL表连接查询(inner join.full join.left join.right join) 前提条件:假设有两个表,一个是学生表,一个是学生成绩表. 表的数据有: 一.内连接-inner ...

  4. SQL 表变量和临时表

    SQL 表变量和临时表 表变量:存储在内存中,作用域是脚本的执行过程中,脚本执行完毕之后就会释放内存,适合短时间内存储数据量小的数据集. 优点:使用灵活,使用完之后立即释放,不占用物理存储空间 缺点: ...

  5. sql表设计器的几个默认值

    sql表设计器的几个默认值: 空字符串‘’(注意是单引号) 当前时间getdate() 逻辑值0或1 汉字或英文字符串需在前面加大写N,并用单引号引起如: N'已发货'

  6. SQL表连接查询

    SQL表连接查询(inner join.full join.left join.right join) 表的数据有: 一.内连接-inner jion : 最常见的连接查询可能是这样,查出学生的名字和 ...

  7. sql表连接left join,right join,inner join三者之间的区别

    sql表连接left join,right join,inner join区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 (以左表数据为基准,不足补为NULL) ...

  8. sql表连接的几种方式

    这里有两张表TableA和TableB,分别是姓名表和年龄表,用于我们例子的测试数据 TableA id name 1 t1 2 t2 4 t4 TableB id age 1 18 2 20 3 1 ...

  9. SQL表连接

    背景 在上次的自考科目<数据库系统原理>中.已经接触到了关于数据库表连接的一些知识,近期的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回想一下. 导图总结 首先用一张思维导图 ...

随机推荐

  1. ZigBee 安全探究

    ZigBee 安全探究 0x02 ZigBee安全机制 (注:对于本节内容,可能在新版ZigBee协议标准中会有所变化,请以新版为准.) ZigBee主要提供有三个等级的安全模式: 1. 非安全模式: ...

  2. 关于Tomcat在eclipse上的配置

    一:安装JDK(建议版本比较新的jdk,因为有很多集成于jdk软件需要的jdk版本比较高): jdk官网下载位置:http://www.oracle.com/technetwork/java/java ...

  3. python成长之路【第十六篇】:JavaScript的高级知识---词法分析

    一.词法分析方法 js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 二.具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active O ...

  4. Linux 系统时间和硬件时间

    linux 的系统时间有时跟硬件时间是不同步的 Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟.系统时钟是指当前Linux Kernel ...

  5. OpenCV2的Mat矩阵形式自定义初始化

    我们知道,OpenCV2的矩阵形式是Mat,那么Mat矩阵的初始化怎么自定义呢 ?由于比较简单,文字部分我就不多加说明了,见代码,有下面几种: //////////////////////////// ...

  6. Skyfree退休公告

    Skyfree退休公告 https://www.itsk.com/thread-372142-1-1.html Skyfree 发表于 2016-11-14 12:26:51 本以为到了这天,会有很多 ...

  7. m.Tomcat使用openssl走APR通道配置单向和双向认证

    引用自: http://blog.csdn.net/gtuu0123/article/details/5827800(Tomcat的SSL单向认证)  http://blog.csdn.net/gtu ...

  8. jQuery Mobile学习日记之HelloWorld

    这里是本人学习jQuery Mobile的过程,主要用于记录,过程中有不对的地方或不严谨的地方,欢予以指出纠正,非常感谢! 1.首先是下载安装以下文件: [Opera Mobile Emulator] ...

  9. 05-String动手动脑问题及课后实验性问题总结

    一.请运行以下实例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? (1)在Java中,内容相同的字符常量("Hello")只保存一 ...

  10. 点击空白处div消失的方法

    这是做的js页面的一部分,也是上一篇文章中加载json格式数据后展示的效果界面. 现在的问题是:点击南京市后会弹出下面的白色的框,点击框右上角的X号后会关闭白色的框,现在想点击白色的框周围的任一地方, ...