你真的会玩SQL吗?系列目录

你真的会玩SQL吗?之逻辑查询处理阶段

你真的会玩SQL吗?和平大使 内连接、外连接

你真的会玩SQL吗?三范式、数据完整性

你真的会玩SQL吗?查询指定节点及其所有父节点的方法

你真的会玩SQL吗?让人晕头转向的三值逻辑

你真的会玩SQL吗?EXISTS和IN之间的区别

你真的会玩SQL吗?无处不在的子查询

你真的会玩SQL吗?Case也疯狂

你真的会玩SQL吗?表表达式,排名函数

你真的会玩SQL吗?简单的 数据修改

你真的会玩SQL吗?你所不知道的 数据聚合

你真的会玩SQL吗?透视转换的艺术

你真的会玩SQL吗?冷落的Top和Apply

你真的会玩SQL吗?实用函数方法汇总

你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(上)

你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(下)

透视转换是一种行列互转的技术,在转过程中可能执行聚合操作,应用非常广泛。

本章与 你真的会玩SQL吗?数据聚合 内容比较重要,还涉及到 你真的会玩SQL吗?Case的用法 的内容,都可以一起看。

下面的例子将使用OpenSchema表,运行创建表:

CREATE TABLE OpenSchema(
objectid INT NOT NULL,
attribute VARCHAR(30) NOT NULL ,
VALUE SQL_VARIANT NOT NULL,
PRIMARY KEY (objectid,attribute)
)
GO INSERT INTO OpenSchema(objectid,attribute,VALUE)
VALUES
(1,N'attr1',CAST(CAST('ABC' AS VARCHAR(10)) AS SQL_VARIANT)),
(1,N'attr2',CAST(CAST(10 AS INT) AS SQL_VARIANT)),
(1,N'attr3',CAST(CAST('' AS SMALLDATETIME) AS SQL_VARIANT)),
(2,N'attr2',CAST(CAST(12 AS INT) AS SQL_VARIANT)),
(2,N'attr3',CAST(CAST('' AS SMALLDATETIME) AS SQL_VARIANT)),
(2,N'attr4',CAST(CAST('Y' AS CHAR(1)) AS SQL_VARIANT)),
(2,N'attr5',CAST(CAST(13.7 AS NUMERIC(9,3)) AS SQL_VARIANT)),
(3,N'attr1',CAST(CAST('xyz' AS VARCHAR(10)) AS SQL_VARIANT)),
(3,N'attr2',CAST(CAST(20 AS INT) AS SQL_VARIANT)),
(3,N'attr3',CAST(CAST('' AS SMALLDATETIME) AS SQL_VARIANT))

将会得到以下输出:

以上VALUE属性保存了多个不同数据类型的值,可以实现要添加新的属性时不用添加列,直接保存。

但是这样查询我们希望把数据旋转为每个属性占一列的传统方式,然后再保存到临时表中处理后续查询称之为透视转换技术。在这里需要回看一下 你真的会玩SQL吗?之逻辑查询处理阶段 对于理解透视转换的步骤是有帮助的。

来看一看经典的行转列实例,如要得到下面的结果怎么做:

透视转换的步骤:

    1. 分组:这里需要为每个对象从多个基础行来创建单独的一列数据,这意味着要对行进行分组,这里依据的是objectid列。
    2. 扩展:从结果列考虑每个唯一的属性都需要一个结果列,对应的是attribute列。这里是attr1,attr2……attr5,列中包含5个表达式。
    3. 聚合:从一组NULL值和已知值中提取出已知值,这就需要使用聚合操作,提取已知值技巧就是使用MAX或MIN函数,这两个会忽略NULL,并返回一个非NULL值,国为只包含一个值的集合最大值和最小值就是这个值。此处对就列是VALUE列。每组中若包含多个非NULL值 ,视情况也可用SUM/AVG。

参考SQL:

SELECT  objectid ,
MAX(CASE WHEN attribute = 'attr1' THEN VALUE
END) AS attr1 ,
MAX(CASE WHEN attribute = 'attr2' THEN VALUE
END) AS attr2 ,
MAX(CASE WHEN attribute = 'attr3' THEN VALUE
END) AS attr3 ,
MAX(CASE WHEN attribute = 'attr4' THEN VALUE
END) AS attr4 ,
MAX(CASE WHEN attribute = 'attr5' THEN VALUE
END) AS attr5
FROM OpenSchema
GROUP BY objectid

这里也可以用PIVOT,不过PIVOT不支持动态透视转换,除了使代码更短外没有什么显著差异,这里就不演示了。

逆透视转换

即列旋转行,常用于规范化数据,如将上面的结果逆转换。

创建表:

CREATE TABLE PvtOpenSchema(
objectid INT NOT NULL,
attr1 VARCHAR(10) NULL ,
attr2 VARCHAR(10) NULL ,
attr3 VARCHAR(10) NULL ,
attr4 VARCHAR(10) NULL ,
attr5 VARCHAR(10) NULL
)

将上面的结果插入此表:

INSERT INTO PvtOpenSchema
(
objectid,attr1,attr2,attr3,attr4,attr5
)
SELECT objectid ,
MAX(CASE WHEN attribute = 'attr1' THEN CAST( VALUE AS VARCHAR(10))
END) AS attr1 ,
MAX(CASE WHEN attribute = 'attr2' THEN CAST( VALUE AS VARCHAR(10))
END) AS attr2 ,
MAX(CASE WHEN attribute = 'attr3' THEN CAST( VALUE AS VARCHAR(10))
END) AS attr3 ,
MAX(CASE WHEN attribute = 'attr4' THEN CAST( VALUE AS VARCHAR(10))
END) AS attr4 ,
MAX(CASE WHEN attribute = 'attr5' THEN CAST( VALUE AS VARCHAR(10))
END) AS attr5
FROM OpenSchema
GROUP BY objectid

结果:

若做到逆转换,将每个objectid 和每个attribute生成结果集中的一行

第一步是为每个甚而行生成5个属性副本,可以通过基础表和每个属性占一行虚拟辅助表执行交叉联接来实现,然后用select 返回objectid和attribute,用case计算值。

可能数据源中会得到与NULL值,如1的attr4,所以还需要对结果进行过滤掉Value为NULL的。

代码如下:

SELECT  objectid ,
attribute ,
VALUE
FROM ( SELECT objectid ,
attribute ,
CASE attribute
WHEN 'attr1' THEN attr1
WHEN 'attr2' THEN attr2
WHEN 'attr3' THEN attr3
WHEN 'attr4' THEN attr4
WHEN 'attr5' THEN attr5
END AS VALUE
FROM PvtOpenSchema
CROSS JOIN ( SELECT 'attr1' AS attribute
UNION ALL
SELECT 'attr2'
UNION ALL
SELECT 'attr3'
UNION ALL
SELECT 'attr4'
UNION ALL
SELECT 'attr5'
) AS attributes
) AS T
WHERE VALUE IS NOT NULL

这里可以使用UNPIVOT表运算符,查询将更简单:

SELECT  objectid ,
attribute ,
VALUE
FROM PvtOpenSchema UNPIVOT ( VALUE FOR attribute IN ( attr1, attr2, attr3, attr4, attr5 ) ) AS a

UNPIVOT会在一个逻辑处理中删除NULL行。

以上只是一个简单的示例,即使现在理解了但在多变的实际应用可能就会迷惘,那时再来对比看看此例。

练习:

           姓名    科目   成绩
张三 语文 80
张三 数学 90
张三 物理 85
李四 语文 85
李四 物理 82
李四 英语 90
李四 政治 70
王五 英语 90

将上表转换为:

           姓名     数学    物理     英语    语文    政治
李四 0 82 90 85 70
王五 0 0 90 0 0
张三 90 85 0 80 0

你真的会玩SQL吗?透视转换的艺术的更多相关文章

  1. 你真的会玩SQL吗?透视转换

    原文:你真的会玩SQL吗?透视转换 透视转换是一种行列互转的技术,在转过程中可能执行聚合操作,应用非常广泛. 本章与 你真的会玩SQL吗?数据聚合 内容比较重要,还涉及到 你真的会玩SQL吗?Case ...

  2. 你真的会玩SQL吗?之逻辑查询处理阶段

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  3. 你真的会玩SQL吗?和平大使 内连接、外连接

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  4. 你真的会玩SQL吗?三范式、数据完整性

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  5. 你真的会玩SQL吗?让人晕头转向的三值逻辑

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  6. 你真的会玩SQL吗?EXISTS和IN之间的区别

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  7. 你真的会玩SQL吗?无处不在的子查询

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  8. 你真的会玩SQL吗?Case也疯狂

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  9. 你真的会玩SQL吗?表表达式,排名函数

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

随机推荐

  1. iOS热更新-8种实现方式

    一.JSPatch 热更新时,从服务器拉去js脚本.理论上可以修改和新建所有的模块,但是不建议这样做. 建议 用来做紧急的小需求和 修复严重的线上bug. 二.lua脚本 比如: wax.热更新时,从 ...

  2. 【Win 10 应用开发】在App所在的进程中执行后台任务

    在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后 ...

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

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

  4. 简记某WebGIS项目的优化之路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 该项目为研究生时的老师牵头,个人已毕业数年,应老师要求协助其 ...

  5. sql的那些事(一)

    一.概述 书写sql是我们程序猿在开发中必不可少的技能,优秀的sql语句,执行起来吊炸天,性能杠杠的.差劲的sql,不仅使查询效率降低,维护起来也十分不便.一切都是为了性能,一切都是为了业务,你觉得你 ...

  6. CSS知识总结(九)

    CSS常用样式 10.自定义动画 1)关键帧(keyframes) 被称为关键帧,其类似于Flash中的关键帧. 在CSS3中其主要以“@keyframes”开头,后面紧跟着是动画名称加上一对花括号“ ...

  7. 自己写的数据交换工具——从Oracle到Elasticsearch

    先说说需求的背景,由于业务数据都在Oracle数据库中,想要对它进行数据的分析会非常非常慢,用传统的数据仓库-->数据集市这种方式,集市层表会非常大,查询的时候如果再做一些group的操作,一个 ...

  8. java面向对象六原则一法则

    1. 单一职责原则:一类只做它该做的事. 2. 里氏替换原则:子类必须能够替换基类(父类),否则不应当设计为其子类. 3. 依赖倒换原则:设计要依赖于抽象而不是具体化. 4. 接口隔离原则:接口要小而 ...

  9. AspNetPager分页控件样式的使用

    分页是Web应用程序中最常用到的功能之一,AspNetPager  简单实用,应用到项目后台中,棒极了! 自定义样式: <style type="text/css"> ...

  10. 为什么很多SaaS企业级产品都熬不过第一年

    因工作缘由,笔者与周边数位SaaS企业级应用的创始人.运营负责人有过深入接触,发现一个有趣的现象:刚起步时,蓝图远志.规划清晰,但是一路下来,却异常艰难,有些甚至熬不过第一年,就关门歇业. 2015年 ...