多列,多排PIVOT

时间:2014-01-31 16:35:42

标签: sql-server-2008-r2 pivot unpivot

考虑我有一个包含以下形式的数据的表:

Foo_FK  MonthCode_FK  Activity_FK  SumResultsX  SumResultsY
-----------------------------------------------------------
1       201312        0            10           2
1       201312        1            5            1
1       201401        0            15           3
1       201401        1            7            2
2       201312        0            9            3
2       201312        1            1            2
2       201401        0            6            2
2       201401        1            17           4

出于我的目的,可以安全地假设此表是由GROUP BY Foo_FK, MonthCode_FK, Activity_FK SUM( ResultsA ), SUM( ResultsB )创建的聚合,Foo_FK, MonthCode_FK, Activity_FK来获取数据,使得{{ 1}}每条记录唯一。

如果出于某种原因我发现在存储过程中PIVOT这个表比使用SSRS更容易解决我需要做的事情(并且无疑后来维护),希望得到以下内容通过矩阵tablix来消费的格式:

Foo_FK  1312_0_X  1312_0_Y  1312_1_X  1312_1_Y  1401_0_X  1401_0_Y  1401_1_X  1401_1_Y  
--------------------------------------------------------------------------------------
1       10        2         5         1         15        3         7         2
2       9         3         1         2         6         2         17        4

我将如何以非精神的方式做这件事?请参考这个SQL Fiddle证明我可能会尝试使用锤子来制造推动钉子的设备。不要担心动态版本,因为我确信一旦我引导了这个测试用例的静态解决方案,我就可以解决这个问题。

现在,我尝试通过以下内容创建Foo_FK, MonthCode_FK集,然后我尝试PIVOTsee the Fiddle for the full mess):

SELECT  Foo_FK = ISNULL( a0.Foo_FK, a1.Foo_FK ),
        MonthCode_FK = ISNULL( a0.MonthCode_FK, a1.MonthCode_FK ),
        [0_X] = ISNULL( a0.SumResultX, 0 ),
        [0_Y] = ISNULL( a0.SumResultY, 0 ),
        [1_X] = ISNULL( a1.SumResultX, 0 ),
        [1_Y] = ISNULL( a1.SumResultY, 0 )
FROM (  SELECT  Foo_FK, MonthCode_FK, Activity_FK, 
                SumResultX, SumResultY
        FROM    dbo.t_FooActivityByMonth
        WHERE   Activity_FK = 0 ) a0
FULL OUTER JOIN (
        SELECT  Foo_FK, MonthCode_FK, Activity_FK, 
                SumResultX, SumResultY
        FROM    dbo.t_FooActivityByMonth
        WHERE   Activity_FK = 1 ) a1
    ON  a0.Foo_FK = a1.Foo_FK;

我遇到了一些excellent advice on this SO question,因此在使用UNPIVOTPIVOT扭转所有内容之前,我正在执行某种形式的MAX,但是如果有更好的方法可以做到这一点,我会全力以赴。

1 个答案:

答案 0 :(得分:3)

您似乎应该首先通过将unpivot应用于SumResultXSumResultY列,然后转动数据来实现此目的:

;with cte as
(
  select Foo_FK, 
    col = cast(MonthCode_FK as varchar(6))+'_'
            +cast(activity_fk as varchar(1))+'_'+sumresult, 
    value
  from dbo.t_FooActivityByMonth
  cross apply
  (
    values 
      ('X', SumResultX),
      ('Y', SumResultY)
  ) c (sumresult, value)
) 
select Foo_FK, 
  [201312_0_X], [201312_0_Y], [201312_1_X], [201312_1_Y],
  [201401_0_X], [201401_0_Y], [201401_1_X], [201401_1_Y]
from cte
pivot
(
  max(value)
  for col in ([201312_0_X], [201312_0_Y], [201312_1_X], [201312_1_Y],
              [201401_0_X], [201401_0_Y], [201401_1_X], [201401_1_Y])
) piv;

请参阅SQL Fiddle with Demo