SQL Pivot的小计和总计

SQL Pivot的小计和总计,sql,sql-server,pivot,Sql,Sql Server,Pivot,当前有一个脚本,该脚本使用当前年份值减去上一年值来创建透视表 use devmreports -- Creates dynamic values for pivot table DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(month) from ABR

当前有一个脚本,该脚本使用当前年份值减去上一年值来创建透视表

use devmreports

-- Creates dynamic values for pivot table
DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(month)
                    from ABR
                    group by ',' + QUOTENAME(month)
                    order by datalength(',' + QUOTENAME(month))
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- Pivot table for YOY change in booked passengers
set @query
=

'SELECT     Region, 
            CityPair, 
            Year, 
            ' + @cols + '


FROM         
(
    SELECT    ABR.Region, 
                ABR.CityPair, 
                ABR.Year, 
                ABR.Month,
                ABR.Adv_B - ABRP.Adv_B as Total
    FROM    ABR LEFT OUTER JOIN
                      ABRP ON  
                      ABR.Month = ABRP.Month AND 
                      ABR.CityPair = ABRP.CityPair) P
                        PIVOT
                        (
                        SUM(Total) 
                        FOR MONTH IN 
                        (
                        '+@cols+'))as pvt'


execute (@Query)
当前透视图如下所示:

+------------+----------+----+-----+-----+----+
|     Region | CityPair | 8  |  9  | 10  | 11 |
+------------+----------+----+-----+-----+----+
|     A      |        1 | 16 |  17 |  18 |  7 |
|     A      |        2 | 17 | -20 | -10 |  1 |
|     B      |        3 |  5 |   8 |   4 | -3 |
|     B      |        4 | 21 |  10 |   3 |  2 |
|     C      |        5 | 15 | -14 | -12 |  1 |
+------------+----------+----+-----+-----+----+
我想要的是:

+-----------------+----------+----+-----+-----+----+
|       Region    | CityPair | 8  |  9  | 10  | 11 |
+-----------------+----------+----+-----+-----+----+
|     A           |        1 | 16 |  17 |  18 |  7 |
|     A           |        2 | 17 | -20 | -10 |  1 |
|     A Total     |          | 33 |  -3 |   8 |  8 |
|     B           |        3 |  5 |   8 |   4 | -3 |
|     B           |        4 | 21 |  10 |   3 |  2 |
|     B Total     |          | 26 |  18 |   7 | -1 |
|     C           |        5 | 15 | -14 | -12 |  1 |
|     C Total     |          | 15 | -14 | -12 |  1 |
|     Grand Total |          | 74 |   1 |   3 |  8 |
+-----------------+----------+----+-----+-----+----+

任何帮助都将不胜感激。

我的建议是查看使用以获取总行数

如果对查询进行硬编码,则基本语法为:

select 
  case 
    when region is null then 'Grand Total' 
    when citypair is null then region +' Total' 
    else region end region,
  coalesce(cast(citypair as varchar(10)), '') citypair,
  sum([8]) [8], 
  sum([9]) [9]
from
(
  select region, citypair, month, total
  from yourtable
) d
pivot
(
  sum(total)
  for month in ([8], [9])
) piv
GROUP BY rollup(region, citypair);
看。然后,要使用动态SQL版本,可以修改代码以使用:

-- Creates dynamic values for pivot table
DECLARE @cols AS NVARCHAR(MAX),
    @colsRollup AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(month)
                    from ABR
                    group by ',' + QUOTENAME(month)
                    order by datalength(',' + QUOTENAME(month))
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsRollup = STUFF((SELECT ', sum(' + QUOTENAME(month)+ ') as '+ QUOTENAME(month)
                    from ABR
                    group by ',' + QUOTENAME(month)
                    order by datalength(',' + QUOTENAME(month))
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- Pivot table for YOY change in booked passengers
set @query
=

'SELECT     
      case 
        when region is null then ''Grand Total'' 
        when citypair is null then region +'' Total' '
        else region end region,
      coalesce(cast(citypair as varchar(10)), '''') citypair, 
            ' + @colsRollup + '


FROM         
(
    SELECT    ABR.Region, 
                ABR.CityPair, 
                ABR.Year, 
                ABR.Month,
                ABR.Adv_B - ABRP.Adv_B as Total
    FROM    ABR LEFT OUTER JOIN
                      ABRP ON  
                      ABR.Month = ABRP.Month AND 
                      ABR.CityPair = ABRP.CityPair
) P
PIVOT
(
  SUM(Total) 
  FOR MONTH IN ('+@cols+')
)as pvt
GROUP BY rollup(region, citypair);'


execute sp_executesql @Query

这就是为什么我更喜欢用聚合而不是枢轴手动旋转。下面是一个查询,它将显示所有总计和总计:

select
    case
        when grouping(Region) = 1 then 'Grand Total'
        when grouping(CityPair) = 1 then Region + ' Total'
        else Region
    end as Region,
    isnull(cast(CityPair as nvarchar(max)), '') as CityPair,
    sum(case when Month = 8 then Value end) as [8],
    sum(case when Month = 9 then Value end) as [9],
    sum(case when Month = 10 then Value end) as [10],
    sum(case when Month = 11 then Value end) as [11]
from test
group by rollup(Region, CityPair)
这里是动态的一个:

declare @stmt nvarchar(max)

select
    @stmt = isnull(@stmt + ',', '') + 
    'sum(case when Month = ' + cast(Month as nvarchar(max)) +
    ' then Value end) as [' + cast(Month as nvarchar(max)) + ']'
from (select distinct Month from test) as a

select @stmt = '
select
    case
        when grouping(Region) = 1 then ''Grand Total''
        when grouping(CityPair) = 1 then Region + '' Total''
        else Region
    end as Region,
    isnull(cast(CityPair as nvarchar(max)), ''''), ' + @stmt + '
from test
group by rollup(Region, CityPair)'

exec sp_executesql @stmt = @stmt
和往常一样,我们试图让它尽可能可读

我建议使用而不是,因为最后一个将被弃用:

使用ROLLUP,此功能将在的未来版本中删除 Microsoft SQL Server。避免在新开发中使用此功能 工作,并计划修改当前使用此功能的应用程序


感谢bluefeet,这非常有用,必须将@colsrollup的动态SQL调整为:选择@colsrollup=STUFFSELECT',将“+QUOTENAMEmonth+”作为“+QUOTENAMEmonth from ABR group by”,将“+QUOTENAMEmonth+”作为“+QUOTENAMEmonth order by datalength”,将“+QUOTENAMEmonth+”和“+QUOTENAMEmonth”作为XML路径的“+QUOTENAMEmonth”,类型为.value”“,“NVARCHARMAX”,1,1,@User272242很高兴您能理解它:@User272242在看不到完整表结构的情况下,您似乎可以更改sql以获得类似于此演示的COL列表-@User272242 with rollup将在未来版本的Microsoft sql Server中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序-