How to calculate grand totals with SQL Server

  • SQL92 define a function of the group by attribute: WITH ROLLUP
  • The WITH ROLLUP will do the grand total.

Applies to:

  • Microsoft SQL Server 2000
  • Microsoft SQL Server 2005
  • Microsoft SQL Server 2008

Data used

use adventureworks;
go

select productid, locationid, quantity 
from production.productinventory
where productid <=350
order by productid, locationid;
go
productid   locationid quantity
----------- ---------- --------
1           1          408
1           6          324
1           50         353
2           1          427
2           6          318
2           50         364
3           1          585
3           6          443
3           50         324
4           1          512
4           6          422
4           50         388
316         5          532
316         10         388
316         50         441
317         1          283
317         5          158
317         50         152
318         1          136
318         5          171
318         50         132
319         1          308
319         5          184
319         50         305
320         1          481
320         5          372
320         50         283
321         1          569
321         5          540
321         50         641
322         1          622
322         5          587
322         50         475
323         1          603
323         5          568
323         50         513
324         1          585
324         5          568
324         50         476
325         1          569
325         6          540
325         60         641
326         1          622
326         6          587
326         60         475
327         5          408
327         10         443
327         50         513
328         5          568
328         10         585
328         50         476
329         5          558
329         10         576
329         50         467
330         5          548
330         10         566
330         50         457
331         5          574
331         10         441
331         50         390
332         5          344
332         10         233
332         50         267
341         1          372
341         50         392
341         60         339
342         1          369
342         50         388
342         60         336
343         1          568
343         50         606
343         60         499
344         1          358
344         50         332
344         60         382
345         1          321
345         50         315
345         60         300
346         1          585
346         50         476
346         60         641
347         1          318
347         50         246
347         60         332
348         1          323
348         50         251
348         60         337
349         1          328
349         50         256
349         60         342
350         5          622
350         10         406
350         50         313

(93 row(s) affected)
  • I only used a small section of the data, products with an ID of less or equal to 350.
  • This sample size is sufficient to demonstrate the WITH ROLLUP .

Grand Total: WITH ROLLUP

select productid, sum(quantity) as 'Ttl Qty'
from production.productinventory
where productid <=350
group by productid with rollup;
go
productid   Ttl Qty
----------- -----------
1           1085
2           1109
3           1352
4           1322
316         1361
317         593
318         439
319         797
320         1136
321         1750
322         1684
323         1684
324         1629
325         1750
326         1684
327         1364
328         1629
329         1601
330         1571
331         1405
332         844
341         1103
342         1093
343         1673
344         1072
345         936
346         1702
347         896
348         911
349         926
350         1341
NULL        39442

(32 row(s) affected)

Please note the differences:

  1. SELECT productid, SUM(quantity) and GROUP BY productid does the subtotals for each product.
  2. GROUP BY productid WITH ROLLUP does the job of the grand total.
  3. No ORDER BY is needed, the order of the productid by is done by the GROUP BY.

The last line is the grand total with: NULL 39442

Grand total proper formatting

Need to replace the grand total of: NULL 39442 with Gd Total: 39442.

select coalesce(cast(productid as varchar(8)), 'Gd Total:') as 'Product', 
       sum(quantity) as 'Ttl Qty'
from   production.productinventory
where  productid <=350
group by productid with rollup;
go
Product   Ttl Qty
--------- -----------
1         1085
2         1109
3         1352
4         1322
316       1361
317       593
318       439
319       797
320       1136
321       1750
322       1684
323       1684
324       1629
325       1750
326       1684
327       1364
328       1629
329       1601
330       1571
331       1405
332       844
341       1103
342       1093
343       1673
344       1072
345       936
346       1702
347       896
348       911
349       926
350       1341
Gd Total: 39442

(32 row(s) affected)
  1. COALESCE(CAST(productid AS VARCHAR(8)), 'Gd Total:') will place the 'Gd Total:' wording.
  2. If the value of productid is null, then the COALESCE will display 'Gd Total:'. The value of productid on the grand total is null. If the value of productid is not null, then it will use the value of the GROUP BY, the productid.
  3. The CAST(productid AS VARCHAR(8)) is needed to convert the numeric productid to a string to allow for 'Gd Total:' or you will get:
Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the varchar value 'Gd Total:' to data type int.