简体   繁体   中英

Adding a total row at the bottom in a SQL Server query

I have two tables in SQL Server 2008 created like:

CompletedRecordsFinal :

IF OBJECT_Id('tempdb..#CompletedRecordsFinal') IS NOT NULL 
   DROP TABLE #CompletedRecordsFinal

SELECT
    C1, C2, C3, COUNT(distinct Id) as TotalRecords
INTO
    #CompletedRecordsFinal
FROM
    #CompletedRecords
GROUP BY  
    C1, C2, C3

Example result:

C1  C2  C3  TotalRecords    
A   B   1       50          
A   B   2       100 

WaitRecordsFinal :

IF OBJECT_Id('tempdb..#WaitRecordsFinal') IS NOT NULL 
   DROP TABLE #WaitRecordsFinal

SELECT 
    C1, C2, C3, COUNT(distinct Id) as TotalWaitRecords
INTO
    #WaitRecordsFinal
FROM
    #WaitRecords
GROUP BY
    C1, C2, C3

Example result:

C1  C2  C3  TotalWaitRecords    
A   B   1       20  
A   B   2       30  

I use these tables with a left outer join like:

SELECT
    w.C1, C.C2, w.C3, TotalWaitRecords, TotalRecords
FROM
    #WaitingRecordsFinal w  
LEFT OUTER JOIN 
    #CompletedRecordsFinal c ON c.C1 = w.C1 
                             AND c.C2 = w.C2 
                             AND c.C3 = w.C3 

What I want is to add a total row at the bottom and I couldn't manage it. I feel I am close but nothing worked like I wanted up to now. I need something like (it doesn't work):

SELECT 
    w.C1, C.C2, w.C3, TotalWaitRecords, TotalRecords
FROM
    #WaitingRecordsFinal w  
LEFT OUTER JOIN
    #CompletedRecordsFinal c ON c.C1 = w.C1 
                             AND c.C2 = w.C2 
                             AND c.C3 = w.C3 
UNION

SELECT
    C1 = 'Total', C2 = 'Total', C3 = -1, TotalWaitRecords, TotalRecords
FROM
    #WaitingRecordsFinal w  
LEFT OUTER JOIN
    #CompletedRecordsFinal c ON c.C1 = w.C1 
                             AND c.C2 = w.C2 
                             AND c.C3 = w.C3 

Example output of what I want:

   C1   C2   C3  TotalRecords   TotalWaitRecords    
    A   B     1     50              20  
    A   B     2     100             30
Total Total  -1     150             50   

Any help would be appreciated.

EDIT: My problem is a little different than the one indicated as duplicate subject. The main problem is I have 3 column for group by. therefore when I do group by C1, C2, C3, with rollup I see that:

.....
X   B       -1  300 500
X   Total   -1  300 500
.....
A   B       -1  56  47
A   Total   -1  56  47
Total   Total   -1  356 547

I just need the most bottom row, not the others. So this solution does not help. How can I get rid of the others except the most bottom Total Total one?

You can use WITH ROLLUP and also use GROUPING() to label the totals.

Select CASE WHEN GROUPING(w.C1) = 1 THEN 'Total' ELSE w.c1
, CASE WHEN GROUPING(C.C2) = 1 THEN 'Total' ELSE c.c2
, CASE WHEN GROUPING(w.C3) = 1 THEN 'Total' ELSE w.c3
, SUM(TotalWaitRecords) AS TotalWaitRecords
, SUM(TotalRecords) AS TotalRecords
from #WaitingRecordsFinal w  
left outer join #CompletedRecordsFinal c 
on c.C1 = w.C1 
and c.C2 = w.C2 
and c.C3 = w.C3 

GROUP BY 
w.C1
, C.C2
, w.C3
with rollup

you can try doing it with a UNION ALL . I tried using a CTE to combine your 2 queries into one..

WITH cte AS 
(
    SELECT  wrf.C1,
            wrf.C2,
            wrf.C3,
            crf.TotalRecords,
            SUM(wrf.TotalWaitRecords) AS TotalWaitRecords
    FROM    (SELECT C1,
                    C2,
                    C3,
                    COUNT(DISTINCT Id) AS TotalWaitRecords
             FROM   #WaitRecords
             GROUP BY C1,
                    C2,
                    C3
            ) wrf
            OUTER APPLY (SELECT crf.C1,
                                crf.C2,
                                crf.C3,
                                SUM(TotalRecords) AS TotalRecords
                         FROM   (SELECT C1,
                                        C2,
                                        C3,
                                        COUNT(DISTINCT Id) AS TotalRecords
                                 FROM   #CompletedRecords
                                 GROUP BY C1,
                                        C2,
                                        C3
                                ) crf
                         WHERE  crf.C1 = wrf.C1
                                AND crf.C2 = wrf.C2
                                AND crf.C3 = wrf.C3
                         GROUP BY crf.C1,
                                crf.C2,
                                crf.C3
                        ) crf
    GROUP BY wrf.C1,
            wrf.C2,
            wrf.C3,
            crf.TotalRecords
)
SELECT  *
FROM    cte
UNION ALL
SELECT  'Total',
        'Total',
        -1,
        SUM(TotalRecords) TotalRecords,
        SUM(TotalWaitRecords) TotalWaitRecords
FROM    cte

SQL Fiddle Demo

If i just use the Temp tables you are creating already, you should be able to simply do this.

IF OBJECT_Id('tempdb..#AllRecordsFinal') IS NOT NULL 
   DROP TABLE #AllRecordsFinal

SELECT  wrf.C1,wrf.C2,wrf.C3,crf.TotalRecords,wrf.TotalWaitRecords 
INTO    #AllRecordsFinal
FROM    #WaitRecordsFinal wrf
OUTER APPLY (
        SELECT  TotalRecords
        FROM    #CompletedRecordsFinal cr
        WHERE   cr.C1 = wrf.C1 AND cr.C2 = wrf.C2 AND cr.C3 = wrf.C3) crf


SELECT  * FROM #AllRecordsFinal
UNION ALL 
SELECT  'Total','Total',-1,
        SUM(TotalRecords),
        SUM(TotalWaitRecords)
FROM    #AllRecordsFinal

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM