http://www.studyofnet.com/news/295.html

本文导读:T-SQL语句中,Pivot运算符用于在列和行之间对数据进行旋转或透视转换,PIVOT命令可以实现数据表的列转行,同时执行聚合运算,UNPIVOT则与其相反,实现数据的行转列。

PIVOT通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT与PIVOT执行相反的操作,将表值表达式的列转换为列值。

通俗简单的说:PIVOT就是行转列,UNPIVOT就是列传行

一、PIVOT实例

1. 建表

建立一个销售情况表,其中,year字段表示年份,quarter字段表示季度,amount字段表示销售额。quarter字段分别用Q1, Q2, Q3, Q4表示一、二、三、四季度。

SQL 代码   复制

 CREATE TABLE SalesByQuarter

    (    year INT,    -- 年份

        quarter CHAR(2),  -- 季度

        amount MONEY  -- 总额

    )

2. 填入表数据

使用如下程序填入表数据。

SQL 代码   复制

SET NOCOUNT ON

    DECLARE @index INT

    DECLARE @q INT

    SET @index = 0

    DECLARE @year INT

    while (@index < 30)

    BEGIN

        SET @year = 2005 + (@index % 4)

        SET @q = (CAST((RAND() * 500) AS INT) % 4) + 1

        INSERT INTO SalesByQuarter VALUES (@year, 'Q' + CAST(@q AS CHAR(1)), RAND() * 10000.00)

        SET @index = @index + 1

    END

3、如果我们要比较每年中各季度的销售状况,要怎么办呢?有以下两种方法:

(1)、使用传统Select的CASE语句查询

在SQL Server以前的版本里,将行级数据转换为列级数据就要用到一系列CASE语句和聚合查询。虽然这种方式让开发人员具有了对所返回数据进行高度控制的能力,但是编写出这些查询是一件很麻烦的事情。

SQL 代码   复制

    SELECT year as 年份

        , sum (case when quarter = 'Q1' then amount else 0 end) 一季度

        , sum (case when quarter = 'Q2' then amount else 0 end) 二季度

        , sum (case when quarter = 'Q3' then amount else 0 end) 三季度

        , sum (case when quarter = 'Q4' then amount else 0 end) 四季度

    FROM SalesByQuarter GROUP BY year ORDER BY year DESC

得到的结果如下:

(2)、使用PIVOT

由于SQL Server 2005有了新的PIVOT运算符,就不再需要CASE语句和GROUP BY语句了。(每个PIVOT查询都涉及某种类型的聚合,因此你可以忽略GROUP BY语句。)PIVOT运算符让我们能够利用CASE语句查询实现相同的功能,但是你可以用更少的代码就实现,而且看起来更漂亮。

SQL 代码   复制

SELECT year as 年份, Q1 as 一季度, Q2 as 二季度, Q3 as 三季度, Q4 as 四季度 FROM SalesByQuarter PIVOT (SUM (amount) FOR quarter IN (Q1, Q2, Q3, Q4) ) AS P ORDER BY YEAR DESC

得到的结果如下:

二、通过下面一个实例详细介绍PIVOT的过程

SQL 代码   复制

SELECT [星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日]--这里是PIVOT第三步(选择行转列后的结果集的列)这里可以用“*”表示选择所有列,也可以只选择某些列(也就是某些天)

FROM WEEK_INCOME --这里是PIVOT第二步骤(准备原始的查询结果,因为PIVOT是对一个原始的查询结果集进行转换操作,所以先查询一个结果集出来)这里可以是一个select子查询,但为子查询时候要指定别名,否则语法错误

PIVOT

(

    SUM(INCOME) for [week] in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])--这里是PIVOT第一步骤,也是核心的地方,进行行转列操作。聚合函数SUM表示你需要怎样处理转换后的列的值,是总和(sum),还是平均(avg)还是min,max等等。例如如果week_income表中有两条数据并且其week都是“星期一”,其中一条的income是1000,另一条income是500,那么在这里使用sum,行转列后“星期一”这个列的值当然是1500了。后面的for [week] in([星期一],[星期二]...)中 for [week]就是说将week列的值分别转换成一个个列,也就是“以值变列”。但是需要转换成列的值有可能有很多,我们只想取其中几个值转换成列,那么怎样取呢?就是在in里面了,比如我此刻只想看工作日的收入,在in里面就只写“星期一”至“星期五”(注意,in里面是原来week列的值,"以值变列")。总的来说,SUM(INCOME) for [week] in([星期一],[星期二],[星期三],[星期四],[星期五],[星期六],[星期日])这句的意思如果直译出来,就是说:将列[week]值为"星期一","星期二","星期三","星期四","星期五","星期六","星期日"分别转换成列,这些列的值取income的总和。

)TBL--别名一定要写

三.UNPIVOT
很明显,UN这个前缀表明了,它做的操作是跟PIVOT相反的,即列转行。UNPIVOT操作涉及到以下三个逻辑处理阶段。
1,生成副本
2,提取元素
3,删除带有NULL的行
UNPIVOT实例
 
SQL 代码   复制
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
INSERT INTO pvt VALUES (4,4,2,5,5,4);
INSERT INTO pvt VALUES (5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5FROM pvt) p
UNPIVOT(Orders FOR Employee IN (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO

上面UNPIVOT实例的分析

UNPIVOT的输入是左表表达式P,第一步,先为P中的行生成多个副本,在UNPIVOT中出现的每一列,都会生成一个副本。因为这里的IN子句有5个列名称,所以要为每个来源行生成5个副本。结果得到的虚拟表中将新增一个列,用来以字符串格式保存来源列的名称(for和IN之间的,上面例子是 Employee )。第二步,根据新增的那一列中的值从来源列中提取出与列名对应的行。第三步,删除掉结果列值为null的行,完成这个查询。

转载于:https://www.cnblogs.com/liuqiyun/p/7600253.html

sql privot相关推荐

  1. java 必备面试必备

    1.JDK 和 JRE 有什么区别? JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含 ...

  2. pandas dataframe数据聚合groupby、agg、privot基于sum统计详解及实例

    pandas dataframe数据聚合groupby.agg.privot基于sum统计详解及实例 知道了sum.那么min.max.mean.median都是举一反三的事情了. 在日常的数据分析中 ...

  3. sql server 纵横表的转换

    在平常的工作中或者面试中,我们可能有遇到过数据库的纵横表的转换问题.今天我们就来讨论下. 1.创建表 首先我们来创建一张表. sql语句: 1 --1. 创建数据表 2 if OBJECT_ID('S ...

  4. sql特殊字符转义,oracle中将字符 ‘ 转义

    oracle中使用sql语句或多或少地会遇到使用特殊字符,比如" ' ",这时,这个单引号就会与前面的单引号匹配,将文本从中间断开,引发问题和错误.这就需要我们进行转义. 而ora ...

  5. weblogic项目java.sql.SQLException: ORA-01861: 文字与格式字符串不匹配 at oracle.jdbc.....错误解决

    原因:数据源配置时间格式问题 解决方案: 1.进入weblogic控制台 2.左侧菜单栏选择Service- JDBC- Data Source 3.选择你的数据源,然后进入Configuration ...

  6. 如何定位并优化慢查询Sql

    根据慢日志定位慢查询SQL. 查询慢日志相关变量,并进行设置: 主要关注下述三个变量: long_query_time.show_query_log_file.show_query_log 慢查询sq ...

  7. Go 学习笔记(55)— Go 标准库 sql (初始化数据库、插入、更新、删除数据库表、单行查询、多行查询、事务处理)

    1. 标准库说明 Go 的标准库中是没有数据库驱动,只提供了驱动接口,有很多第三方实现了驱动,我们这里选择 go-sql-driver 这个实现是目前使用最多的.github 地址是:https:// ...

  8. SQL与NoSQL的区别 以MySQL与MongoDB为例

    异同对比 1.语言和结构层面 SQL数据库,是基于表的,并且用结构化语言也就是SQL来定义和操纵数据.一方面,这是非常强大的:SQL是最通用和最广泛使用的选项之一,使其成为一个安全的选择,尤其适用于复 ...

  9. 【Sql Server】数据库的3大服务

    在数据库SQL SERVER中,处理常用的sql server数据库引擎,还有其他3大服务,分别是集成服务,报表服务,分析服务. 集成服务商可以配置包,这里的包可以理解是数据库引擎里的用户数据库.可以 ...

最新文章

  1. Linux学习笔记十四周一次课(5月9日)
  2. stackover flow载入巨慢
  3. DPDK 初识DPDK(十五)
  4. 开个坑, 写个阿里云开放储存服务(OSS)的C++版SDK以及客户端
  5. Windows10配置Git远程连接到github(全网简单教程)
  6. python爬虫什么意思-python的爬虫是什么意思
  7. SpringBoot 下 Mybatis 的缓存
  8. linux查看db2表空间大小,DB2查看表空间大小及使用情况
  9. OC容器——图书馆 .h 文件
  10. u盘写保护+计算机管理,U盘写保护的解决方法
  11. ElasticSearch教程——倒排索引及其数据结构以及优缺点
  12. pythonppt生成替换_python生成ppt的方法
  13. request域中放入参数几种方法
  14. Access仿Excel的RoundUp函数向上取整的方法。
  15. LGG7刷入第三方ROM,安卓11
  16. u盘制作启动盘后空间容量变小解决方法
  17. html5图片邀请函,html5,邀请函.doc
  18. 前端及后端项目开发工具
  19. 北大ACM原创题目:母牛的故事(距离推理)
  20. [源代码]基于D-S证据理论的雷达探测信息融合

热门文章

  1. java上传文件文件保存后损坏_Laravel存储文件在上传时会损坏
  2. c#往结构体里面读数据_结构体内存对齐,这回给你彻底搞会!
  3. 离线缓存占内存吗_彻底弄懂浏览器缓存策略
  4. java 解析二进制_java实现解析二进制文件(字符串、图片)
  5. 用c语言设计一个任意20个数升序排列,编写一个用选择法对一维数组升序排序的函数,并在主函数中调用该排序函数,实现对任意20个整数的排序。...
  6. 内网网段范围_局域网中多网段的划分
  7. 【spring boot】新建项目,实现HelloWorld
  8. java解析日志数据_Java实时监控日志文件并输出的方法详解
  9. echarts词云图形状_用Python 3.8绘制词云图就这么20行代码
  10. python3 字典添加_python3字典删除元素和添加元素的几种方法