Skip to main content
4 of 13
typos
Erwin Brandstetter
  • 186.6k
  • 28
  • 465
  • 639

You mostly answered the question yourself already. I have a few morsels to add:

In PostgreSQL (and probably other RDBMS that support the boolean type) you can use the boolean result of the test directly. Cast it to integer and SUM():

SUM((invoice_amount > 100)::int)) 

Or use it in a NULLIF() expression and COUNT():

COUNT(NULLIF(invoice_amount > 100, FALSE)) 

Or with a simple OR NULL:

COUNT((invoice_amount > 100) OR NULL) 

Performance is practically identical in my experience. But to verify I ran a quick test with EXPLAIN ANALYZE on a real life table in PostgreSQL 9.1.6.

74208 of 184568 rows qualified with the condition kat_id > 50. All queries return the same result. I ran each like 10 times in turns to exclude caching effects and appended the best result as note:

SELECT SUM((kat_id > 50)::int) FROM log_kat -- 438 ms SELECT COUNT(NULLIF(kat_id > 50, FALSE)) FROM log_kat -- 437 ms SELECT COUNT(CASE WHEN kat_id > 50 THEN 1 END) FROM log_kat -- 437 ms SELECT count((kat_id > 50) OR NULL) FROM log_kat -- 436 ms SELECT SUM(CASE WHEN kat_id > 50 THEN 1 ELSE 0 END) FROM log_kat -- 432 ms 

The CASE expressions seem to be slightly faster. I remember tests where it was the other way round, though. Either way, hardly any real difference in performance. ###Faster alternative If the whole affair is as simple as your test case (most of the time it isn't), you can just rewrite to:

SELECT count(*) FROM log_kat WHERE kat_id > 50; -- 202 ms (!) 

Which is the real king of performance and can also easily utilize an index.

Erwin Brandstetter
  • 186.6k
  • 28
  • 465
  • 639