in

ASP.NET Weblogs

Nick Wilczynski

SUM(Case) in SQL

While answering some questions in the forums, I notice that there are a lot questions that have queries that could be quickly modified to make them more efficient. Queries like:

SELECT (SELECT SUM(Column1) FROM MyTable WHERE Column2 = 'Some Value') as FieldNeeded1,

(SELECT SUM(Column1) FROM MyTable WHERE Column2 = 'Some Other Value') as FieldNeeded2,

(SELECT SUM(Column1) FROM MyTable WHERE Column2 = 'Some Other Value 3') as FieldNeeded3, ETC

 

Can be easily rewritten as :

SELECT SUM(CASE WHEN Column2 = 'Some Value' THEN Column1 ELSE 0 END) as FieldNeeded1,

SUM(CASE WHEN Column2 = 'Some Other Value' THEN Column1 ELSE 0 END) as FieldNeeded2,

SUM(CASE WHEN Column2 = 'Some Other Value 3' THEN Column1 ELSE 0 END) as FieldNeeded3

FROM MyTable

 

While it might not save much on a small table, think when the there are a million records. Running a select 3 times to pull the same fields would be very inefficient. However, this method is very efficient because the select only has to happen once, and the data is then just summarized as it is needed.

Anybody else have some very simple tips to increase peoples query performance?

Published Jun 03 2008, 01:28 PM by nick-w
Filed under:

Comments

 

Geek Bully said:

Brilliant! This statement rocks. Thank you! Thank you!

February 6, 2009 4:02 PM
 

irenilda said:

Legal serviu muito bem para mim, faça um exemplo para converter um varchar dentro do case pois eu não sei como colocar valeu

March 13, 2009 8:09 AM
 

SeibGuy said:

So why can't I:

SELECT     SUM(CASE WHEN rm40401.docabrev = 'CR' THEN - rm20101.CURTRXAM ELSE (CASE WHEN rm40401.docabrev = 'PMT' THEN - rm20101.CURTRXAM ELSE

                      (CASE WHEN rm40401.docabrev = 'RTN' THEN - rm20101.CURTRXAM ELSE rm20101.CURTRXAM END) END) END) AS AMOUNT,

                     RM20101.CUSTNMBR, RM00101.CUSTNAME, RM40401.DOCABREV

FROM         RM20101 INNER JOIN

                     RM00101 ON RM20101.CUSTNMBR = RM00101.CUSTNMBR INNER JOIN

                     RM40401 ON RM20101.RMDTYPAL = RM40401.RMDTYPAL

March 24, 2009 10:44 PM
 

RickPetersen said:

I think you're missing a part of how case works... it's a case structure used specifically so you don't have to nest conditional logic (if statements, et all).  Your query rewritten like below should work (except for anything I fat-finger):

SELECT SUM(CASE WHEN rm40401.docabrev = 'CR' THEN -rm20101.CURTRXAM

WHEN rm40401.docabrev = 'PMT' THEN -rm20101.CURTRXAM

WHEN rm40401.docabrev = 'RTN' THEN -rm20101.CURTRXAM

ELSE rm20101.CURTRXAM END)

AS AMOUNT,

                    RM20101.CUSTNMBR, RM00101.CUSTNAME, RM40401.DOCABREV

FROM RM20101 INNER JOIN

    RM00101 ON RM20101.CUSTNMBR = RM00101.CUSTNMBR INNER JOIN

    RM40401 ON RM20101.RMDTYPAL = RM40401.RMDTYPAL

Or even more concisely

SELECT SUM(CASE WHEN rm40401.docabrev in ('CR','PMT','RTN') THEN -rm20101.CURTRXAM

ELSE rm20101.CURTRXAM END)

AS AMOUNT,

                    RM20101.CUSTNMBR, RM00101.CUSTNAME, RM40401.DOCABREV

FROM RM20101 INNER JOIN

    RM00101 ON RM20101.CUSTNMBR = RM00101.CUSTNMBR INNER JOIN

    RM40401 ON RM20101.RMDTYPAL = RM40401.RMDTYPAL

April 29, 2009 2:51 PM
 

Emanuel said:

Great explanation and examples for a novice like me.

Thanks.

July 15, 2009 1:00 PM

Leave a Comment

(required)  
(optional)
(required)  
Add