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中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序-