2
$SQL = "SELECT pc.dist_id, pc.route, pc.types,
        COUNT( pc.types = '$type' ) total,
        COUNT( pc.types = '$type' AND pc.options = '1') 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 如何与 () 中的多个列一起工作。

4

2 回答 2

2

Count也可以:

SELECT pc.dist_id, pc.route, pc.types,
COUNT( CASE WHEN pc.types = '$type' THEN 1 END) total,
COUNT( CASE WHEN pc.types = '$type' AND pc.options = '1' THEN 1 END) 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返回非 NULL 值的数量,并且CASE具有默认值ELSE NULL...

于 2012-12-21T17:57:33.147 回答
1

另一个稍短的变体(性能与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,FALSENULL
您只想计算TRUE案件。
所以转换FALSENULL,一切都很时髦。

或者,甚至更短,但不是更快:

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;
于 2012-12-26T06:27:51.517 回答