SQL SERVER技术内幕之7 透视与逆透视

时间:2023-03-08 22:13:57

1.透视转换

透视数据(pivoting)是一种把数据从行的状态旋转为列的状态的处理,在这个过程中可能须要对值进行聚合。

SQL SERVER技术内幕之7 透视与逆透视

SQL SERVER技术内幕之7 透视与逆透视

每个透视转换将涉及三个逻辑处理阶段,每个阶段都有相关的元素:分组阶段处理相关的分组或行元素,扩展(spreading)阶段处理相关的扩展或列元素,聚合阶段处理相关的聚合元素和聚合函数。例子中的分组元素是empid,扩展元素为custid,聚合函数为SUM(),聚合元素为qty。

(1)使用标准SQL进行透视转换

SELECT empid,
SUM(CASE WHEN custid = ‘A’ THEN qty END) AS A,
SUM(CASE WHEN custid = ‘B’ THEN qty END) AS B,
SUM(CASE WHEN custid = ‘C’ THEN qty END) AS C,
SUM(CASE WHEN custid = ‘D’ THEN qty END) AS D
FROM dbo.Orders GROUP BY empid

(2)使用T-SQL PIVOT运算符进行透视转换

SELECT empid,A,B,C,D
FROM(SELECT empid,custid,qty
FROM dbo.Orders ) AS D
PIVOT(SUM(qty) FOR custid IN(A,B,C,D)) AS P

PIVOT 运算符隐式地把源表(或表表达式)中既没有指定为扩展元素,也没有指定为聚合元素的那些元素作为分组元素,所以在使用PIVOT运算符时,须要保证PIVOT运算符的源表除了分组、扩展和聚合元素以外,不能再包含其他属性。

2.逆透视转换

逆透视转换是一种把数据从列的状态旋转为行的状态的技术。
SQL SERVER技术内幕之7 透视与逆透视

现在要求逆透视转换数据,为每个雇员和客户组合返回一行记录,其中包含这一组合的订货量,期望的输出结果应该如下所示:
SQL SERVER技术内幕之7 透视与逆透视

(1)使用标准SQL进行逆透视转换
标准SQL解决方案非常明确地要实现3个逻辑处理阶段:生成副本、提取元素和删除不相关的交叉。

...解决方案的第一步是根据来源表的每一行生成多个副本,在这个例子,需要为A、B、C、D 4个列分别生成一个副本

SELECT *
FROM dbo.EmpCustOrders
CROSS JOIN(VALUES('A'),('B'),('C'),('D')) AS Custs(custid);

实现解决方案的第一步操作后,返回以下输出结果:

...第二步是生成一个数据列,由它返回与当前副本所代表的客户相对应的列值。具体到本例而言,如果当前custid的值为A,则qty列应该返回A列的值,如果当前custid的值为B,则qty列应该返回B列的值。
SQL SERVER技术内幕之7 透视与逆透视

实现解决方案的第二步之后,生成以下输出结果:
SQL SERVER技术内幕之7 透视与逆透视

...第三步删除不相关的交叉
SQL SERVER技术内幕之7 透视与逆透视
(2)使用T-SQL的UNPIVOT运算符进行逆透视转换

SELECT empid,custid,qty
FROM dbo.EmpCustOrders
UNPIVOT(qty FOR custid IN(A,B,C,D)) AS U;