你真的会玩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 attr5 FROM OpenSchema GROUP BY objectid