【问题标题】:Adding Grand Totals in Pivot Table在数据透视表中添加总计
【发布时间】:2012-11-29 03:09:11
【问题描述】:

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

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)

但是我想做的是为每个投资组合 ID 添加总计,我不确定如何实现这一点。有什么帮助吗?

【问题讨论】:

  • 您要将总计作为附加行还是作为列?
  • 我想要一个总计行

标签: sql-server tsql pivot dynamic-sql


【解决方案1】:

您应该能够添加 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

【讨论】:

  • 看起来不错,但有几件事。我怎样才能让“总计”出现在持续时间段列中?我怎样才能按 DurationSort 排序枢轴,但将总数保持在底部?
  • @chrissyp 我更新了代码以删除 null 并将其替换为 durationband 列中的 total。我不确定你的意思是通过durationsort 订购pivot,你能用一些示例数据改变sql fiddle,然后解释所需的结果吗?
  • 感谢@bluefeet 的编辑,但我仍然可以按 DurationSort 对其进行排序。它必须像在某处添加 ORDER BY DurationSort 一样简单?基本上,持续时间排序只是一个从 1、2、3 运行的 INT ......所以我可以将持续时间带刺排序为正确的顺序。我想我已经正确更新了 SQL Fiddle。
  • @chrissyp 你能提供 sql fiddle 的链接吗?
  • 可能是一个垃圾示例:sqlfiddle.com/#!3/959fa/1 基本上我希望 DurationBand 以正确的顺序排列,所以我创建了 DurationSort 来强制它
猜你喜欢
  • 2019-04-15
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多