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)) 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.439 ms SELECT COUNT(NULLIF(kat_id > 50, FALSE)) FROM log_kat -- 437.291 ms SELECT COUNT(CASE WHEN kat_id > 50 THEN 1 END) FROM log_kat -- 432.731 ms SELECT SUM(CASE WHEN kat_id > 50 THEN 1 ELSE 0 END) FROM log_kat -- 431.780 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. But if the whole affair is as simple as your test case (most of the time isn't), you can just rewrite to:
SELECT count(*) FROM log_kat WHERE kat_id >50; -- 201.579 ms Which is the real king of performance and can also easily utilize an index where appropriate.