Saturday, April 28, 2012

Insisting ELSE 0 on COUNT aggregate? You might as well substitute your birthday

Some unenlightened SQL user from stackoverflow wanted to do this, note the ELSE 0 part:

select count(case when 'blah' = 'bleh' then 1 else 0 end) 
from information_schema.tables

Due to his insistence on the need for ELSE 0 part, I recommended to him that he can substitute his birthday instead on that ELSE part, it "works" the same anyway as the ELSE 0 approach:

select 
count(case when 'blah' = 'bleh' then 1 else 'April 20, 1939' end) 
from information_schema.tables


Of course, both queries above are a crime against humanity, and I cannot let this wrong deed goes unpunished uncorrected, here's the correct query:

Idiomatic MySQL (duality between boolean and integer) :

select sum('blah' = 'bleh') 
from information_schema.tables


Idiomatic Postgresql:

select sum(('blah' = 'bleh')::int) 
from information_schema.tables


SQL Server:

select sum(case when 'blah' = 'bleh' then 1 end) 
from information_schema.tables


We can also use these, but the above works well, free of noise and devoid of Cargo Cult Programming, it's better to use that code. SUM ignores 0 and NULLs, why include them?

select sum(case when 'blah' = 'bleh' then 1 else 0 end) 
from information_schema.tables;

select sum(case when 'blah' = 'bleh' then 1 else null end) 
from information_schema.tables;


But for the love of our craft, don't do this (the ELSE 0 on COUNT), this is very wrong :
select count(case when 'blah' = 'bleh' then 1 else 0 end) 
from information_schema.tables


If you insist so, re-read from the top

No comments:

Post a Comment