使用SQL Server RollUP进行汇总 - 但仅保留最后一个汇总?

23

我有一个查询:

DECLARE @t TABLE(NAME NVARCHAR(MAX),datee date,val money)

insert INTO @t SELECT 'a','2012-01-02',100
insert INTO @t SELECT 'a','2012-01-02',100
insert INTO @t SELECT 'a','2012-01-03',100
insert INTO @t SELECT 'a','2012-01-05',100
insert INTO @t SELECT 'b','2012-01-06',200
insert INTO @t SELECT 'b','2012-01-07',200
insert INTO @t SELECT 'd','2012-01-07',400
insert INTO @t SELECT 'e','2012-01-09',500
insert INTO @t SELECT 'f','2012-01-12',600

SELECT  Name,datee,SUM (val) 
from @t GROUP BY NAME ,datee 

目前的结果为:

图片描述

但我需要在末尾添加sum。 所以我尝试使用rollup:

 SELECT  Name,datee,SUM (val) 
    from @t GROUP BY NAME ,datee  with ROLLUP

输入图像描述

但我只需要最后一行的总计。 我不需要报告内的 sum's

那么如何得到所需结果?

(我不能更改 group by 子句,因为其他人也需要它,我只想在末尾添加 sum,带/不带 rollup)。

在线 sql 在这里

4个回答

41

您可以使用 GROUPING SETS 来实现此功能,尝试以下代码:

SELECT  Name,datee,SUM (val) 
FROM    @t 
GROUP BY 
        GROUPING SETS((NAME ,datee), ())

SQL Fiddle


@RoyiNamir 不用谢,这是标准的 TSQL 功能,但并不经常使用(我猜),所以人们并不总是知道它 :) - Ivan Golović
@RoyiNamir 我相信你可以在网上找到相关资源,我在一本书中读到过它(尽管我不太记得使用过它)。 - Ivan Golović
3
@RoyiNamir - 我所遇到的最好的解释是由Itzik Ben Gan提供的第1部分第2部分 - Martin Smith
2
你也可以在《MCTS自学培训套件(考试70-433):Microsoft® SQL Server® 2008数据库开发》中找到一些例子和解释,但这是一本纸质书。 - Ivan Golović
伊万,看起来从现在开始我可以忘记 group by a,b,c 并开始做 group by grouping sets(a,b,c) 作为未来 sum 的准备(如果我需要的话)......对吗? - Royi Namir
@RoyiNamir 如果仅在确实需要时使用 GROUPING SETS。如果普通的 GROUP BY 满足您的要求,我会坚持使用它。我不知道 GROUP BY GROUPING SETSGROUP BY col1, col2 之间是否存在任何性能差异...这取决于特定的情况,但我倾向于以尽可能简单的方式处理事情。 - Ivan Golović

12

使用ROLLUP()也是可能的:

SELECT
  Name,
  datee,
  SUM (val) 
FROM @t 
GROUP BY 
  ROLLUP((NAME, datee))
;

WITH ROLLUPWITH CUBE是非标准且已弃用的语法。(请参见GROUP BY手册中的非ISO兼容语法。)

需要注意的是,在SQL Server 2005或更低版本的兼容性级别下,不支持ROLLUP();在SQL Server 2008+或更高版本的兼容性级别下,也不支持ROLLUP(),但支持GROUPING SETS()


4

如果您只需要最终总数,那么您可以使用 UNION ALL

SELECT  Name,datee,SUM (val) 
from @t 
GROUP BY NAME ,datee 
union all
SELECT  null,null,SUM (val) 
from @t

请查看带演示的SQL Fiddle

或者您可以使用WHERE子句来过滤掉具有null值的行:

select name, 
  datee, 
  total
from
(
  SELECT  Name,datee,SUM (val) total
  from @t 
  GROUP BY NAME, datee with rollup
) src
where datee is not null
or
(
  name is null 
  and datee is null
)

请参见 带有演示的SQL Fiddle 结果为:
|   NAME |      DATEE | COLUMN_2 |
----------------------------------
|      a | 2012-01-02 |      200 |
|      a | 2012-01-03 |      100 |
|      a | 2012-01-05 |      100 |
|      b | 2012-01-06 |      200 |
|      b | 2012-01-07 |      200 |
|      d | 2012-01-07 |      400 |
|      e | 2012-01-09 |      500 |
|      f | 2012-01-12 |      600 |
| (null) |     (null) |     2300 |

FYI @t 是一个查询的结果。(它无所谓) 所以我不得不写两次。我尝试使用CTE来做,但是:http://i.stack.imgur.com/hYhOk.jpg - Royi Namir
@RoyiNamir 好的,第二个应该可以胜任,因为没有 union all。 - Taryn

1
你可以使用这个查询:

SELECT  *
FROM    ( SELECT    Name ,
                    datee ,
                    SUM(val) summ
          FROM      @t
          GROUP BY  NAME ,
                    datee
                    WITH ROLLUP
        ) A
WHERE   ( datee IS NOT NULL
          OR ( datee IS NULL
               AND name IS NULL
             )
        )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接