在数据透视表中添加Grand Totals

时间:2012-12-11 14:56:23

标签: sql-server tsql pivot dynamic-sql

我使用以下代码创建了一个数据透视表:

DECLARE @SQL AS VARCHAR(MAX)
DECLARE @Columns AS VARCHAR (MAX)

SELECT @Columns =
COALESCE(@Columns + ', ','')+ QUOTENAME(PortfolioID)
FROM
(
SELECT PortfolioID FROM InfoPortal.DBO.fn_Generic_PortfolioGroupMembers (@PortfolioGroup)
) AS B
ORDER BY B.PortfolioID

SET @SQL = '
WITH PivotData AS
(
    SELECT 
        PortfolioID, Percentage, DurationBand, DurationSort 
    FROM #Worktable
)

SELECT 
    DurationBand, 
    ' + @Columns + '
FROM PivotData
PIVOT
(
    SUM(Percentage)
    FOR PortfolioID
    IN (' + @Columns + ')
) AS PivotResult
ORDER BY DurationSort'

EXEC (@SQL)

然而,我想要做的是为每个portfolioID添加总计,我不确定如何实现这一目标。有什么帮助吗?

1 个答案:

答案 0 :(得分:3)

您应该可以添加GROUP BY with ROLLUP来生成总计行,类似于:

DECLARE @SQL AS VARCHAR(MAX)
DECLARE @Columns AS VARCHAR (MAX)
DECLARE @ColumnsRollup AS VARCHAR (MAX)

SELECT @Columns =
COALESCE(@Columns + ', ','')+ QUOTENAME(PortfolioID)
FROM
(
    SELECT distinct PortfolioID 
    FROM worktable
) AS B
ORDER BY B.PortfolioID

SELECT @ColumnsRollup =
COALESCE(@ColumnsRollup + ', Sum(','Sum(')+ QUOTENAME(cast(PortfolioID as varchar(10)))+') as Portfolio'+cast(PortfolioID as varchar(10))
FROM
(
    SELECT distinct PortfolioID 
    FROM worktable
) AS B
ORDER BY B.PortfolioID

SET @SQL = '
            WITH PivotData AS
            (
                SELECT PortfolioID, Percentage, DurationBand, DurationSort 
                FROM Worktable
            )
            SELECT case when DurationBand is not null then cast(durationband as varchar(10))
                else ''Total'' end Durationband, ' + @ColumnsRollup+ '
            FROM
            (
                SELECT DurationBand, ' + @Columns + '
                FROM PivotData
                PIVOT
                (
                    SUM(Percentage)
                    FOR PortfolioID IN (' + @Columns + ')
                ) AS PivotResult
            ) src
            GROUP BY DurationBand with ROLLUP'

EXEC (@SQL)

SQL Fiddle with Demo注意:示例数据仅根据您的表结构进行模拟。

结果:

| DURATIONBAND | PORTFOLIO1 | PORTFOLIO2 | PORTFOLIO3 |
-------------------------------------------------------
|            2 |         78 |     (null) |     (null) |
|            5 |     (null) |     (null) |          4 |
|           12 |         10 |         45 |     (null) |
|        Total |         88 |         45 |          4 |

根据需要对事物进行排序,您可以使用:

DECLARE @SQL AS VARCHAR(MAX)
DECLARE @Columns AS VARCHAR (MAX)
DECLARE @ColumnsRollup AS VARCHAR (MAX)

SELECT @Columns =
COALESCE(@Columns + ', ','')+ QUOTENAME(PortfolioID)
FROM
(
    SELECT distinct PortfolioID 
    FROM worktable
) AS B
ORDER BY B.PortfolioID

SELECT @ColumnsRollup =
COALESCE(@ColumnsRollup + ', Sum(','Sum(')+ QUOTENAME(cast(PortfolioID as varchar(10)))+') as '+QUOTENAME(cast(PortfolioID as varchar(10)))
FROM
(
    SELECT distinct PortfolioID 
    FROM worktable
) AS B
ORDER BY B.PortfolioID

SET @SQL = '
            WITH PivotData AS
            (
                SELECT PortfolioID, Percentage, DurationBand, DurationSort 
                FROM Worktable
            )
            SELECT *
            FROM
            (
                SELECT DurationBand, ' + @Columns + '
                FROM PivotData
                PIVOT
                (
                    SUM(Percentage)
                    FOR PortfolioID IN (' + @Columns + ')
                ) AS PivotResult
                UNION ALL
                select ''Grand Total'', '+@ColumnsRollup+'
                from
                (
                    SELECT DurationBand, ' + @Columns + '
                    FROM PivotData
                    PIVOT
                    (
                        SUM(Percentage)
                        FOR PortfolioID IN (' + @Columns + ')
                    ) AS PivotResult
                )tot
            ) src
            '

EXEC (@SQL)

请参阅SQL Fiddle with Demo