如何从透视表创建“总计”列和页脚?

时间:2015-11-02 19:43:21

标签: sql sql-server tsql

我有一个包含warehouse, product, and available列的清单表,如下所示:

warehouse    product    available
John2196     KITCOMP01    7
John2196     KITCOMP01    12
John2196     KITCOMP02    7
JohnS196     KITCOMP01    9
JohnS196     KITCOMP03    1

仓库列旋转以创建:

product    John2196    JohnS196
KITCOMP01     19          9
KITCOMP02     7          NULL
KITCOMP03    NULL         1

使用此代码

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)

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

set @query = 'SELECT product,' + @cols + ' from 
         (
            select product, warehouse, available
            from tlninventory
        ) x
        pivot 
        (
            sum(available)
            for warehouse in (' + @cols + ')
        ) p '

execute(@query)

现在我需要获取Total Column和Total Footer Row,同时忽略NULL值,但由于标头是通过pivot创建的,所以此查询将在具有不同仓库和产品的多个表上运行,这意味着标题永远不会是同样,我无法总结this thread建议的静态列。

作为参考,我需要一个类似于:

的决赛桌
product    John2196    JohnS196    Total
KITCOMP01     19          9         28
KITCOMP02     7          NULL       7
KITCOMP03    NULL         1         1
Total         26          10        36

1 个答案:

答案 0 :(得分:1)

你需要在这里做一些事情。

首先创建一个新变量来存储' sum(仓库)'列

DECLARE @cols AS NVARCHAR(MAX),
        @sumCols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)

创建类似于常规透视列名称的总和列

select @sumCols = STUFF((SELECT ',' + 'SUM(' + QUOTENAME(Warehouse) + ')' + QUOTENAME(Warehouse)
                from tlninventory
                group by Warehouse
                order by Warehouse
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') ,1,1,'')

现在您需要创建一个您的数据透视查询的cte,但添加一个窗口sum() over()来获取行总数..

set @query = ' WITH cte AS  
        (
            SELECT product,' + @cols + ', Total from 
             (
                select product, warehouse, available, sum(available) over (partition by product) total
                from tlninventory
            ) x
            pivot 
            (
                sum(available)
                for warehouse in (' + @cols + ')
            ) p 
        ) 

现在您使用总和列在末尾结合总列。

set @query = ' WITH cte AS  
        (
            SELECT product,' + @cols + ', Total from 
             (
                select product, warehouse, available, sum(available) over (partition by product) total
                from tlninventory
            ) x
            pivot 
            (
                sum(available)
                for warehouse in (' + @cols + ')
            ) p 
        ) 
        SELECT product,' + @cols + ', Total FROM (
            SELECT *, ''a'' sortCol 
            FROM cte 
            UNION ALL 
            SELECT ''Total'', ' + @sumCols + ', sum(total), ''z''
            FROM cte 
        ) a
        ORDER BY sortCol, product'

execute(@query)

SQL Fiddle