SQL透视转换
来源:互联网 发布:碰碰交友软件 编辑:程序博客网 时间:2024/06/03 14:52
透视转换是一种行列互转的技术,在转过程中可能执行聚合操作,应用非常广泛。
本章与 你真的会玩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('20070101' AS SMALLDATETIME) AS SQL_VARIANT)),(2,N'attr2',CAST(CAST(12 AS INT) AS SQL_VARIANT)),(2,N'attr3',CAST(CAST('20090101' 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('20080101' AS SMALLDATETIME) AS SQL_VARIANT))
将会得到以下输出:
以上VALUE属性保存了多个不同数据类型的值,可以实现要添加新的属性时不用添加列,直接保存。
但是这样查询我们希望把数据旋转为每个属性占一列的传统方式,然后再保存到临时表中处理后续查询称之为透视转换技术。在这里需要回看一下 你真的会玩SQL吗?之逻辑查询处理阶段 对于理解透视转换的步骤是有帮助的。
来看一看经典的行转列实例,如要得到下面的结果怎么做:
透视转换的步骤:
- 分组:这里需要为每个对象从多个基础行来创建单独的一列数据,这意味着要对行进行分组,这里依据的是objectid列。
- 扩展:从结果列考虑每个唯一的属性都需要一个结果列,对应的是attribute列。这里是attr1,attr2……attr5,列中包含5个表达式。
- 聚合:从一组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 attr5FROM OpenSchemaGROUP 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 attr5FROM OpenSchemaGROUP BY objectid
结果:
若做到逆转换,将每个objectid 和每个attribute生成结果集中的一行
第一步是为每个甚而行生成5个属性副本,可以通过基础表和每个属性占一行虚拟辅助表执行交叉联接来实现,然后用select 返回objectid和attribute,用case计算值。
可能数据源中会得到与NULL值,如1的attr4,所以还需要对结果进行过滤掉Value为NULL的。
代码如下:
SELECT objectid , attribute , VALUEFROM ( 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 TWHERE VALUE IS NOT NULL
这里可以使用UNPIVOT表运算符,查询将更简单:
SELECT objectid , attribute , VALUEFROM 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透视转换
- SQL中的透视转换
- 透视转换
- 用SQL行列转换实现数据透视的一些思考
- SQL SERVER透视转换(行旋转列)
- T-SQL 透视&逆透视
- 通过sql做数据透视表,数据库表行列转换(pivot和Unpivot用法)(一)
- 三维效果(透视转换)
- 【SQL server】透视及分组
- 3D转换加上透视效果
- opencv3_java 图像透视视角转换Perspective warpPerspective
- [python笔记]行列转换,数据透视
- 透视
- 透视
- SQL Server 生成数据透视表
- SQL点滴19—T-SQL中的透视和逆透视
- [数据透视表] 如何使用透视表对表格形式进行转换?[示例]
- 动态数据透视表pivot table(行转换列)
- 网页优先选择模式
- bzoj1935.园丁的烦恼 (离散化 && 树状数组)
- 设置相关:版本号,清除缓存
- android dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent的响应流程
- Maven学习总结(10)——使用Maven编译项目gbk的不可映射问题
- SQL透视转换
- RAC One Node的Failover
- servlet编写留言板
- mipi LCD 的CLK时钟频率与显示分辨率及帧率的关系
- framebuffer
- 机器学习复习——GBDT
- tableView 属性已经其协议方法
- Docker1.8 官方中文文档
- 微信公众平台开发者模式(1)JAVA版接入