2017-06-23 152 views
1

我试图在动态数据透视表中创建总计和小计的查询。在动态数据透视表中计数小计和总数

我有3列的表格:
enter image description here

如何获得导致这样?

enter image description here

这是查询我有,但我不能创建和总量小计:

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) 

我感谢您的帮助,谢谢。

回答

1

另一种方式来做到这一点使用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('')方法进行串接。

2

你可以使用GROUP BY GROUPING SETS计算Total itemPivot

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 

演示链接:http://rextester.com/GTKM34090

+0

使用[GROUPING](https://docs.microsoft.com/en-us/sql/t-sql/functions/grouping-transact-sql)而不是'Case'语句。 –

+1

所用的连接方法不能保证能正常工作。总是最好使用'xml path()'。希望你不介意说这些建议 –

+0

我刚刚复制了OP的代码。 :) – TriV