2013-01-23 13 views
14

Ho questa query:Somma con server SQL RollUP - ma solo l'ultimo riepilogo?

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 

attualmente il risultato è:

enter image description here

ma ho bisogno di aggiungere sum alla fine. Così ho provato con rollup:

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

enter image description here

ma ho solo bisogno l'ultima riga totale somma. Non ho bisogno del in-reportsum's

Quindi come può ottenere il risultato del desiderio?

(Non posso modificare la clausola group by perché anche altri ne hanno bisogno, voglio solo sommare alla fine con/senza rollup).

sql online is here

risposta

27

E 'possibile con GROUPING SETS, provate questo:

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

SQL Fiddle

+0

@RoyiNamir Prego, è una funzionalità standard di TSQL, ma non viene utilizzata così spesso (credo) così la gente non sempre lo sa a riguardo :) –

+0

Ho davvero bisogno di leggerlo. –

+0

@RoyiNamir Sono sicuro che troverai le risorse su di esso online, ho letto su di esso in un libro (anche se non mi ricordo davvero di usarlo). –

4

Se si desidera solo il totale finale, non può semplicemente utilizzare un UNION ALL:

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

Vedi SQL Fiddle with Demo

oppure è possibile utilizzare una clausola WHERE per filtrare le righe con i valori 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 
) 

Vedi SQL Fiddle with Demo

Il risultato è:

| 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 | 
+0

FYI @t è il risultato di una query. (non importa), così male devo scriverlo due volte. Ho provato a farlo con CTE ma: http://i.stack.imgur.com/hYhOk.jpg –

+0

@RoyiNamir Beh, il secondo, dovrebbe funzionare perché non c'è nessuna unione tutti – Taryn

9

E' possibile anche con ROLLUP():

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

WITH ROLLUP, nonché WITH CUBE, non standard e deprecato. (Vedere non conforme a ISO Sintassi nel manuale GROUP BY.)

Si deve rilevare che ROLLUP() non è supportato in livello di compatibilità sotto di 90 in SQL Server 2005 o sotto 100 in SQL Server 2008+, mentre GROUPING SETS() è .

1

È possibile utilizzare questa query:

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 
      ) 
     )