2012-12-11 45 views
1

我创建了一个数据透视表用下面的代码:添加透视表的总计

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,我不确定如何做到这一点。任何帮助?

+0

你想总计作为附加行或作为一个列? – Taryn

+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'', '[email protected]+' 
       from 
       (
        SELECT DurationBand, ' + @Columns + ' 
        FROM PivotData 
        PIVOT 
        (
         SUM(Percentage) 
         FOR PortfolioID IN (' + @Columns + ') 
        ) AS PivotResult 
       )tot 
      ) src 
      ' 

EXEC (@SQL) 

SQL Fiddle with Demo

+0

看起来不错,但有几件事。我如何让“总计”出现在持续时间栏中?我如何通过DurationSort命令来确定总数,但总数保持在底部? –

+0

@chrissyp我更新了代码以删除null,并用'durationband'列中的'total'替换它。我不确定你的意思是按'durationsort'命令'pivot',你可以用一些示例数据改变sql小提琴,然后解释所需的结果吗? – Taryn

+0

感谢编辑@bluefeet,但我仍然可以通过DurationSort进行排序。它必须像在某处添加ORDER BY DurationSort一样简单?基本上,持续时间排序仅仅是一个从1,2,3开始的INT ......这样我就可以将持续时间带刺入正确的顺序。我想我已经正确更新了SQL小提琴。 –