将表转换为数据透视表

时间:2013-09-14 03:46:28

标签: sql sql-server pivot

我想知道是否可以翻译下表:

enter image description here

进入这样的数据透视表?

enter image description here

我尝试了下面的查询,但它没有给我正确的结果:

SELECT * FROM
(
    select 
        WorkWeek
        , CometsFT
        , CometsTR
        , CSP
        , MaxCIMFT
        , MaxCIMTR
        , MaxCIMWS
        , STD
    from tblLotTrackingDetails
) s
pivot
(
    sum(cometsft)
    for WorkWeek in (WW6, WW7, WW8, WW9, WW10)
)as piv

2 个答案:

答案 0 :(得分:1)

您必须先UNPIVOT您的牌桌然后PIVOT再次

WITH unpivot_details AS
(
  SELECT WorkWeek, Type, Value
    FROM 
  ( 
    SELECT WorkWeek, CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD
      FROM tblLotTrackingDetails 
  ) s
  UNPIVOT
  ( 
    Value FOR Type IN (CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD) 
  ) s
)
SELECT Type RowLabels, 
       WW1, WW2, WW3, WW4, WW5, WW6, WW7, WW8, WW9, WW10
  FROM
(
  SELECT WorkWeek, Type, Value
    FROM unpivot_details
  UNION ALL
  SELECT WorkWeek, 'Total', SUM(Value) Value
    FROM unpivot_details
   GROUP BY WorkWeek
) s
PIVOT
(
  SUM(Value) FOR WorkWeek IN(WW1, WW2, WW3, WW4, WW5, WW6, WW7, WW8, WW9, WW10)
) p
 ORDER BY CASE WHEN Type = 'Total' THEN 1 ELSE 0 END,
          Type

示例输出:

| ROWLABELS | WW1 | WW2 | WW3 | WW4 | WW5 | WW6 | WW7 | WW8 | WW9 | WW10 |
|-----------|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
|  CometsFT |  42 |  50 |  30 |  45 |  25 |  36 |  26 |  33 |  35 |   35 |
|  CometsTR |  20 |  14 |  30 |  28 |  24 |  14 |  21 |  18 |  21 |    9 |
|       CSP |   6 |   4 |   1 |   7 |   9 |   8 |   8 |   2 |   4 |    3 |
|  MaxCIMFT |  52 |  58 | 105 |  77 |  42 |  39 |  34 |  23 |  34 |   19 |
|  MaxCIMTR |  21 |   2 |   7 |   9 |  34 |   4 |   5 |   7 |   7 |    9 |
|  MaxCIMWS |  28 |  29 |  59 |  82 |  24 |  26 |  19 |  20 |  40 |   21 |
|       STD |   3 |  40 |   2 |   8 |   2 |   5 |   5 |   2 |   9 |    2 |
|     Total | 172 | 197 | 234 | 256 | 160 | 132 | 118 | 105 | 150 |   98 |

这是 SQLFiddle 演示


根据您的评论

更新。此查询将提取第11周到第15周的数据。

WITH unpivot_details AS
(
  SELECT WorkWeek, Type, Value
    FROM 
  ( 
    SELECT WorkWeek, CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD
      FROM tblLotTrackingDetails 
     WHERE WorkWeek IN ('WW11', 'WW12', 'WW13', 'WW14', 'WW15')
  ) s
  UNPIVOT
  ( 
    Value FOR Type IN (CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD) 
  ) s
)
SELECT Type RowLabels, 
       WW11, WW12, WW13, WW14, WW15
  FROM
(
  SELECT WorkWeek, Type, Value
    FROM unpivot_details
  UNION ALL
  SELECT WorkWeek, 'Total', SUM(Value) Value
    FROM unpivot_details
   GROUP BY WorkWeek
) s
PIVOT
(
  SUM(Value) FOR WorkWeek IN(WW11, WW12, WW13, WW14, WW15)
) p
 ORDER BY CASE WHEN Type = 'Total' THEN 1 ELSE 0 END,
          Type

这是 SQLFiddle 演示

答案 1 :(得分:0)

最后,经过大量的尝试,我能够做我想做的事情。 peterm的建议奏效了。对于共享,以下是我将使用的动态支点:

DECLARE @Columns NVARCHAR(MAX)
        ,@query NVARCHAR(MAX)
SELECT @Columns = STUFF(
 (SELECT  ', ' +'['+WorkWeek+']' FROM
 (SELECT TOP 10 WorkWeek FROM(SELECT TOP 10 WorkWeek , LotTrackingID    FROM tblLotTracking ORDER BY LotTrackingID DESC) s Order by s.LotTrackingID) AS T FOR XML PATH('')),1,2,'') 

SET @query = N'WITH unpivot_details AS
(
  SELECT WorkWeek, Type, Value
    FROM 
  ( 
    SELECT WorkWeek, CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD
      FROM tblLotTrackingDetails 
  ) s
  UNPIVOT
  ( 
    Value FOR Type IN (CometsFT, CometsTR, CSP, MaxCIMFT, MaxCIMTR, MaxCIMWS, STD) 
  ) s
)
SELECT Type RowLabels, 
       ' + @Columns + '
  FROM
(
  SELECT WorkWeek, Type, Value
    FROM unpivot_details
  UNION ALL
  SELECT WorkWeek, ''Total'', SUM(Value) Value
    FROM unpivot_details
   GROUP BY WorkWeek
) s
PIVOT
(
  SUM(Value) FOR WorkWeek IN(' + @Columns + ')
) p
 ORDER BY CASE WHEN Type = ''Total'' THEN 1 ELSE 0 END,
          Type';
EXEC sp_executesql @query;