旋转或不旋转
Posted
技术标签:
【中文标题】旋转或不旋转【英文标题】:Pivot or unpivot 【发布时间】:2014-03-29 01:01:21 【问题描述】:我有一个包含每小时统计数据的表格,我需要转置(或取消转置?)
起始表的格式为:
[SystemID] [Hour] [CallStarts] [AvgDuration]
1 0 3 27
1 1 10 58
1 2 43 45
1 3 54 63
2 0 6 56
2 1 46 98
2 2 56 67
2 3 65 77
我需要输出是:
[SystemID] [Statistic] [Hr0] [Hr1] [Hr2] [Hr3]
1 CallStarts 3 10 43 54
1 AvgDuration 27 58 45 63
2 CallStarts 6 46 56 65
2 AvgDuration 56 98 67 77
我使用的是 SQL Server 2008R2。我了解数据透视表的基础知识,但对它们没有太多经验。它的 [Statistic] 列让我不知所措。
【问题讨论】:
【参考方案1】:这是一种无需数据透视即可获得这些结果的方法,具体取决于索引和数据大小,它可能会更快:
SELECT SystemID,
MAX('CallStarts') AS Statistic,
SUM(CASE WHEN Hour = 0 THEN CallStarts ELSE 0 END) AS Hr0,
SUM(CASE WHEN Hour = 1 THEN CallStarts ELSE 0 END) AS Hr1,
SUM(CASE WHEN Hour = 2 THEN CallStarts ELSE 0 END) AS Hr2,
SUM(CASE WHEN Hour = 3 THEN CallStarts ELSE 0 END) AS Hr3
FROM Table
GROUP BY SystemID
UNION ALL
SELECT SystemID,
MAX('AvgDuration') AS Statistic,
SUM(CASE WHEN Hour = 0 THEN AvgDuration ELSE 0 END) AS Hr0,
SUM(CASE WHEN Hour = 1 THEN AvgDuration ELSE 0 END) AS Hr1,
SUM(CASE WHEN Hour = 2 THEN AvgDuration ELSE 0 END) AS Hr2,
SUM(CASE WHEN Hour = 3 THEN AvgDuration ELSE 0 END) AS Hr3
FROM Table
GROUP BY SystemID
ORDER BY SystemID, Statistic ASC
【讨论】:
谢谢,这些都非常有帮助。我决定使用联合方法,因为将来由该领域的人更容易维护。性能不是问题。另外,当我一直在研究这种情况时,很明显有些数据需要额外的处理,所以我不能使用直轴。【参考方案2】:您可以单独查询每种类型的统计信息,然后将它们合并。我在 SQL Fiddle 上使用了 @attila 构建的相同架构。
WITH callS AS (SELECT systemid, hour, callstarts FROM t),
callD AS (SELECT systemid, hour, avgduration FROM t)
SELECT systemid, 'callStarts' AS [statistics], [0] as Hr0, [1] as Hr1, [2] as Hr2, [3] AS Hr3
FROM callS pivot (max(callStarts) FOR hour IN ([0], [1], [2], [3])) AS p
UNION ALL
SELECT systemid, 'AvgDuration' AS [statistics], [0], [1], [2], [3]
FROM callD pivot (max(avgduration) FOR hour IN ([0], [1], [2], [3])) AS p2
ORDER BY systemid, [statistics] DESC;
可以在这里看到输出:http://www.sqlfiddle.com/#!3/eb109/20/0
【讨论】:
【参考方案3】:您的想法是正确的……先取消旋转,然后再旋转。也许有更好的方法,但这有效:
SELECT *
FROM (
SELECT SystemId, [Hour], [Stat], [Statistics]
FROM
(SELECT systemid, [hour], CallStarts, AvgDuration FROM t) nt
UNPIVOT
(stat FOR [Statistics] IN (CallStarts, AvgDuration)) AS ut
) AS ap
PIVOT
(SUM (Stat) FOR [Hour] IN ([0], [1], [2], [3], [4])) AS p
ORDER BY [SystemId], [Statistics] DESC
这是一个显示它工作的 sqlfiddle:http://www.sqlfiddle.com/#!3/eb109/8/0
【讨论】:
谢谢,这是正确的。您可能想在末尾添加order by [systemid]
。
感谢您的建议。我已经添加了订单。以上是关于旋转或不旋转的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D游戏物体操作 ③ ( 旋转操作 | 旋转工具 | 基本旋转 | 设置旋转属性 | 增量旋转 | 缩放操作 | 轴向缩放 | 整体缩放 | 操作工具切换 | 操作模式切换 )