Avoid calling COUNT twice in CASE expression (PostgreSQL)

时间:2015-06-15 14:42:22

标签: sql postgresql

Inside a larger query, I have to COUNT a variable, then if it is larger than 1, have the count as a string otherwise an empty string:

CASE COUNT(measurement.id) > 1 THEN to_char(COUNT(measurement.id),' 999') ELSE ''

I'm afraid this is slow because I use COUNT() twice. Is there a better way?

1 个答案:

答案 0 :(得分:3)

This expression:

CASE COUNT(measurement.id) > 1 THEN to_char(COUNT(measurement.id),' 999') ELSE ''

is not slow because COUNT() is called twice. The hard work of aggregating the data is the part where the key values are brought together. The individual aggregation functions are generally not particularly expensive (there are exceptions such as COUNT(DISTINCT)). So, even if it were being called multiple times, this would not be an issue.

You could change the query to something more cryptic like:

coalesce(to_char(nullif(count(measurement.id), 0), '999')), '')

This takes a count of 0, converts it to NULL, which is then turned into an empty string (and I think it would only evaluate the argument once in Postgres, although SQL Server would evaluate it twice, in which case you use isnull() instead of coalesce()). I much prefer your version, if you feel the need to convert nice numbers into strings.

EDIT:

COUNT() appears to be defined as "immutable" which is even stronger than "stable". I'm not even sure if this is correct, but that is the case on SQL Fiddle. In any case, it probably isn't called twice, but the expensive part is the GROUP BY anyway.