SQL数据透视表 - 复制Excel功能

时间:2010-06-30 14:54:24

标签: tsql sql-server-2008 pivot-table

假设我有一张这样的表:

Task   Type   Variable   Hours    Duration
One    A      X          10       5
One    A      Y          40       15
One    B      X          100      29
Two    A      X          5        2
Two    B      X          15       9
Two    A      Y          60       17
Three  A      Y          18       5

任务类型变量的组合使每一行都是唯一的。

如何获得如下所示的数据透视表:

                            X        Y
One     A      Hours        10       40
               Duration     5        15
One     B      Hours        100      0     
               Duration     29       0
Two     A      Hours        5        60
               Duration     2        17
Two     B      Hours        15       0
               Duration     9        0
Three   A      Hours        0        18
               Duration     0        5

这在SQL中是否可行?我知道Excel可以做到这一点。

1 个答案:

答案 0 :(得分:1)

这是一个真正的UNPIVOTPIVOT。以下代码在单个查询中实现了所需的结果。

DECLARE @t TABLE (
    Task     varchar(5),
    Type     char(1),
    Variable char(1),
    Hours    int,
    Duration int
    ) 

INSERT INTO @t
    VALUES
        ('One',   'A', 'X',  10,  5),
        ('One',   'A', 'Y',  40, 15),
        ('One',   'B', 'X', 100, 29),
        ('Two',   'A', 'X',   5,  2),
        ('Two',   'B', 'X',  15,  9),
        ('Two',   'A', 'Y',  60, 17),
        ('Three', 'A', 'Y',  18,  5)

SELECT
        P.Task,
        P.Type,
        CAST(P.Property AS varchar(8)) AS Property,
        COALESCE(P.X, 0) AS X,
        COALESCE(P.Y, 0) AS Y
    FROM @t AS T
    UNPIVOT (
        Value FOR Property IN (
            Hours,
            Duration
            )
        ) AS U
    PIVOT (
        SUM(Value) FOR Variable IN (
            X,
            Y
            )
        ) AS P

这会产生以下结果。

Task  Type Property X           Y
----- ---- -------- ----------- -----------
One   A    Duration 5           15
One   A    Hours    10          40
One   B    Duration 29          0
One   B    Hours    100         0
Three A    Duration 0           5
Three A    Hours    0           18
Two   A    Duration 2           17
Two   A    Hours    5           60
Two   B    Duration 9           0
Two   B    Hours    15          0

如您所见,小时和持续时间会被翻转。我认为没有办法单独使用PIVOT来强制执行订单。通过使用Property值和相关的排序顺序连接到另一个表,可以很容易地解决这个问题,只要您有其他方法可以确保其他列首先正确排序。