SQL 动态数据透视表 table 包含 ROW 和 Column Total

SQL Dynamic Pivot table with ROW and Column Total

E_ID Full_name      Dept        fy_week fy_rev
45  Tom Smith       Sales       201801  100
65  Mike Tod        Marketing   201801  50
12  Chris Thomson   Sales       201803  60
85  Paul Henry      Sales       201804  40
32  Mich Dowell     Sales       201802  50
65  Mike Tod        Marketing   201803  70
12  Chris Thomson   Sales       201802  80
85  Paul Henry      Sales       201803  90

我在SQLtable中有以上数据。我可以在没有总计列的情况下通过动态数据透视查询创建以下 table。数据透视列之前需要总计列,底部需要总计行。

E_ID Full_name      Dept    Total   201801  201802  201803  201804
12  Chris Thomson   Sales   0        [=13=]            [=13=]
32  Mich Dowell     Sales            [=13=]        [=13=]     [=13=]
45  Tom Smith       Sales   0      0       [=13=]  [=13=]     [=13=]
65  Mike Tod    Marketing   0              [=13=]      [=13=]
85  Paul Henry      Sales   0        [=13=]       [=13=]     
Total                       0      0     0 0       

以前也有人问过类似的问题,但我没能按照我的要求重构。这是我的代码:

DECLARE 
@cols   AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(fy_week) y
        FROM my_sample_table z
        ORDER BY y asc
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @query = 'SELECT e_id, full_name, dept, ' + @cols + ' 
    from ( select e_id, full_name, dept from my_sample_table ) x
       pivot 
        ( Sum(fy_rev) for fy_week in (' + @cols + ')) p '
execute(@query)

假设:

  • fy_week是字符串数据类型

要获取按列总计,请添加到您的查询中 x

from 
( 
    -- your original query
    select E_ID, Full_name, Dept, fy_week, fy_rev -- you missed the fy_week & fy_rev here
    from   my_sample_table 

    -- add the following few lines : union all & select query
    union all

    select E_ID, Full_name, Dept, fy_week = ''Total'', fy_rev = sum(fy_rev)
    from   my_sample_table 
    group by E_ID, Full_name, Dept
) x

@cols 需要附加列名 Total。在您的 set @cols 查询

之后添加以下内容
select  @cols = '[Total],' + @cols

对于行级查询,您将需要另一个按 fy_week 分组的查询,为此,我使用了 CTE,因为您需要引用上面的 x 查询两次

完整的查询。 (为了我的眼睛我重新格式化了一下)

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(fy_week) y
            FROM my_sample_table z
            ORDER BY y asc
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')

SET @cols = '[Total],' + @cols           -- added this line

-- added cte query
SET @query  = '
    ; with cte as
    (
            select  E_ID, Full_name, Dept, 
                    fy_week = convert(varchar(10), fy_week), fy_rev 
            from    my_sample_table 

            union all

            select  E_ID, Full_name, Dept, 
                    fy_week = ''Total'', fy_rev = sum(fy_rev) 
            from    my_sample_table 
            group by E_ID, Full_name, Dept
    )
    SELECT E_ID, Full_name, Dept, ' 
        + @cols + ' 
    from 
    ( 
        select  E_ID, Full_name, Dept, fy_week, fy_rev 
        from    cte

        -- the following is for row wise total
        union all

        select  E_ID = 99, Full_name = ''Total'', Dept = '''', fy_week, sum(fy_rev) 
        from    cte 
        group by fy_week
    ) x
    pivot 
    ( 
        Sum(fy_rev) 
        for fy_week in (' + @cols + ')
    ) p '

-- print out to validate
print   @query
execute(@query)

编辑:更改为处理 fy_week 是整数列