我确定我在这里遗漏了一些东西。
我有一个这样的数据集:
FK RowNumber 值类型状态 1 1 aaaaa A 新 1 2 bbbbb B 好 1 3 ccccc A 坏 1 4 ddddd C 好 1 5 eeeee B 好 2 1 fffff C 坏 2 2 ggggg 一个新的 2 3 hhhhh C 不好 3 1 iiiiii 好 3 2 jjjjj 好
我想查询前 3 个结果并将它们作为列进行透视,因此最终结果集如下所示:
FK 值 1 类型 1 状态 1 值 2 类型 2 状态 2 值 3 类型 3 状态 3 1 aaaaa A 新 bbbbb B 好 ccccc A 坏 2 fffff C 坏 ggggg A 新 hhhhh C 坏 3 iiiiii 好 jjjjj 好
如何在 SQL Server 2005 中完成此操作?
我一直在尝试使用PIVOT进行此操作,但我仍然对该关键字非常不熟悉,并且无法让它按照我想要的方式工作。
SELECT * --Id, [1], [2], [3]
FROM
(
SELECT Id, Value, Type, Status
, ROW_NUMBER() OVER (PARTITION BY Id ORDER Status, Type) as [RowNumber]
FROM MyTable
) as T
PIVOT
(
-- I know this section doesn't work. I'm still trying to figure out PIVOT
MAX(T.Value) FOR RowNumber IN ([1], [2], [3]),
MAX(T.Type) FOR RowNumber IN ([1], [2], [3]),
MAX(T.Status) FOR RowNumber IN ([1], [2], [3])
) AS PivotTable;
我的实际数据集比这个复杂一点,我需要前 10 条记录,而不是前 3 条,所以我不想简单地CASE WHEN RowNumber = X THEN...
为每一条都做。
更新
我测试了下面的所有答案,发现它们中的大多数看起来都差不多,在较小的数据集(大约 3k 条记录)中没有明显的性能差异,但是在对较大的数据集运行查询时略有不同。
这是我使用 80,000 条记录并查询前 10 行中的 5 列的测试结果,所以我的最终结果集是 50 列 +Id
列。我建议您自己测试它们,以确定哪一种最适合您和您的环境。
bluefoot对数据进行反透视和重新透视的答案平均最快,大约为 12 秒。我也喜欢这个答案,因为我发现它最容易阅读和维护。
Aaron 的回答和koderoid 的回答都建议使用
MAX(CASE WHEN RowNumber = X THEN ...)
, 并且在 13 秒左右的平均值之后紧随其后。Rodney使用多个
PIVOT
语句的答案平均约为 16 秒,尽管使用较少的 PIVOT 语句可能会更快(我的测试有 5 个)。亚伦回答的前半部分建议使用 CTE 并且
OUTER APPLY
是最慢的。我不知道运行需要多长时间,因为我在 2 分钟后取消了它,那是大约 3k 条记录、3 行和 3 列而不是 80k 记录、10 行和 5 列。