另一个稍短的变体(性能与CASE语句大致相同):
SELECT pc.dist_id, pc.route, pc.types
,COUNT(NULLIF(pc.types = '$type', FALSE) AS total
,COUNT(NULLIF(pc.types = '$type' AND pc.options = '1', FALSE) AS callbacks
FROM per_call pc
WHERE pc.types = '$type'
GROUP BY pc.dist_id, pc.route, pc.types
ORDER BY pc.dist_id, pc.route;
它背后的原理是:
COUNT计算所有非空值。
表达式产生一个布尔值,它可以是TRUE,FALSE或NULL。
您只想计算TRUE案件。
所以转换FALSE为NULL,一切都很时髦。
或者,甚至更短,但不是更快:
SELECT pc.dist_id, pc.route, pc.types
,sum((pc.types = '$type')::int) AS total
,sum((pc.types = '$type' AND pc.options = '1')::int) AS callbacks
FROM per_call pc
WHERE pc.types = '$type'
GROUP BY pc.dist_id, pc.route, pc.types
ORDER BY pc.dist_id, pc.route;
强制boolean转换为 1,转换integer为0。因此,有效。TRUEFALSEsum()
既然你有pc.types = '$type'asWHERE条件,你可以简化为:
SELECT pc.dist_id, pc.route, pc.types
,COUNT(*) AS total -- slightly faster, too
,COUNT(NULLIF(pc.options = '1', FALSE) AS callbacks
FROM per_call pc
WHERE pc.types = '$type'
GROUP BY pc.dist_id, pc.route, pc.types
ORDER BY pc.dist_id, pc.route;