在 Dynamic Pivot 中计算小计和总计 Sql

Count Sub Total and Total in Dynamic Pivot Sql

我正在尝试在动态数据透视表中创建一个包含总计和小计的查询。

我有一个包含 3 列的 table:

如何得到这样的结果?

这是我的查询,但我无法创建总计和小计:

DECLARE @Columns as VARCHAR(MAX)

SELECT @Columns =
COALESCE(@Columns + ', ','') + QUOTENAME(item)
from @mytable

DECLARE @SQL as VARCHAR(MAX)
SET @SQL = 
'SELECT name, location, ' + @Columns + '
FROM
(
    SELECT name, location, item
    FROM @mytable

) as PivotData
PIVOT
(
    count(item)
    for item  IN (' + @Columns + ')
) AS PivotResult
'

EXEC(@SQL)

感谢您的帮助,谢谢。

您可以在 Pivot

之前使用 GROUP BY GROUPING SETS 计算 Total item
CREATE TABLE #SampleData
(
    Name varchar(10),
    Location varchar(20),
    Item varchar(10)
)

INSERT INTO #SampleData
VALUES
('Ron', 'Loc A', 'Pencil'),
('Ron', 'Loc A', 'Pencil'),
('Ron', 'Loc B', 'Pen'),
('Ron', 'Loc B', 'Laptop'),
('Tom', 'Loc A', 'Pencil'),
('Tom', 'Loc B', 'Pencil'),
('Tom', 'Loc B', 'Pen'),
('Tom', 'Loc A', 'Pencil'),
('Tom', 'Loc A', 'Laptop'),
('Tom', 'Loc A', 'Pencil')


DECLARE @Columns as VARCHAR(MAX)

SELECT @Columns =
COALESCE(@Columns + ', ','') + QUOTENAME(sd.item)
from (select DISTINCT item from #SampleData) sd

DECLARE @SQL as VARCHAR(MAX)
SET @SQL = 
'SELECT name, location, ' + @Columns + '
FROM
(
    SELECT  CASE WHEN sd.Location is null then ''Total '' + sd.Name
             ELSE sd.Name
          END as Name, 
          sd.Name as GroupName,
          sd.Location, sd.item, count(item) AS CountValue
    FROM #SampleData sd
    GROUP BY GROUPING SETS ((sd.Name, sd.Location, sd.item),(sd.Name, sd.item))

) as PivotData
PIVOT
(
    sum(CountValue)
    for item  IN (' + @Columns + ')
) AS PivotResult
Order by GroupName, name
'

EXEC(@SQL)

DROP TABLE #SampleData

演示 link:http://rextester.com/GTKM34090

使用 ROLLUPGROUPING

的另一种方法
DECLARE @Pivot_Columns  AS VARCHAR(MAX),
        @select_Columns VARCHAR(max)

SELECT @Pivot_Columns = Stuff((SELECT DISTINCT ',' + Quotename(item) FROM #SampleData FOR xml path('')), 1, 1, '')
SELECT @select_Columns = Stuff((SELECT DISTINCT ',Sum(' + Quotename(item) + ') as '+Quotename(item) FROM #SampleData FOR xml path('')), 1, 1, '')

DECLARE @SQL AS VARCHAR(MAX)

SET @SQL = 'SELECT case when grouping(location) = 1 and grouping(name) = 0 then ''Total''+ '' '' + name 
when grouping(location) = 1 and grouping(name) = 1 then ''Total'' 
else name end Name, location, '
           + @select_Columns + '
FROM
(
    SELECT name, location, item
    FROM #SampleData

) as PivotData
PIVOT
(
    count(item)
    for item  IN ('
           + @Pivot_Columns + ')
) AS PivotResult
group by name,location with rollup 
'

EXEC(@SQL) 

注意:我更改了将行连接成逗号分隔值的方式。您当前的字符串连接方法不能保证始终有效。我使用 For Xml Path('') 方法进行连接。