在 SQL Server 2008 中,您可以使用 PIVOT 查询非常轻松地处理此任务。以下示例依赖于将数据转换为以下格式(看起来您已经完成了):
Name Month Value
---------- ------- -----
District 1 Month 1 10
District 1 Month 2 5
District 1 Month 3 6
District 2 Month 1 1
District 2 Month 2 2
District 2 Month 3 3
District 3 Month 1 8
District 3 Month 2 6
District 3 Month 3 11
如果你能做到这一点,那么你的 PIVOT 查询应该如下所示:
DECLARE @myTable AS TABLE([Name] VARCHAR(20), [Month] VARCHAR(20), [Value] INT)
INSERT INTO @myTable VALUES ('District 1', 'Month 1', 10)
INSERT INTO @myTable VALUES ('District 1', 'Month 2', 5)
INSERT INTO @myTable VALUES ('District 1', 'Month 3', 6)
INSERT INTO @myTable VALUES ('District 2', 'Month 1', 1)
INSERT INTO @myTable VALUES ('District 2', 'Month 2', 2)
INSERT INTO @myTable VALUES ('District 2', 'Month 3', 3)
INSERT INTO @myTable VALUES ('District 3', 'Month 1', 8)
INSERT INTO @myTable VALUES ('District 3', 'Month 2', 6)
INSERT INTO @myTable VALUES ('District 3', 'Month 3', 11)
SELECT [Name], [Month 1], [Month 2], [Month 3], [NameTotalValue] AS [Total]
FROM
(
SELECT [Name], [Month], [Value],
SUM([Value]) OVER (PARTITION BY [Name]) as [NameTotalValue]
FROM @myTable
UNION
SELECT 'Total', [Month], SUM([Value]), (SELECT SUM([Value]) FROM @myTable)
FROM @myTable
GROUP BY [Month]
) t
PIVOT
(
SUM([Value]) FOR [Month] IN ([Month 1], [Month 2], [Month 3])
) AS pvt
ORDER BY pvt.[Name]
在这个例子中,我使用了SUM([Value]) OVER PARTITION
获得每个区的总和,然后我做了一个 UNION 将总计行添加到底部。结果如下:
Name Month 1 Month 2 Month 3 Total
----------- ------- ------- ------- -----
District 1 10 5 6 21
District 2 1 2 3 6
District 3 8 6 11 25
Total 19 13 20 52
关于这种方法,您会注意到的一件事是,您必须提前知道想要在表顶部显示的列名称。如果您将报表设置为运行一整年,那么这很容易做到,但如果列数发生变化,那就更棘手了。如果您要允许用户指定自定义日期范围(即 07/2011-10/2011 或 06/2011-11/2011),则处理该要求的一种方法是使用动态 SQL 构建 PIVOT 查询然后执行它sp_executesql http://msdn.microsoft.com/en-us/library/ms188001.aspx.