简化了。初稿是最优的。
要在一个查询中计算所有内容:
SELECt p.id ,(100 * sum((a.price > 0)::int)) / cc.ct AS commercial ,(100 * sum((a.price = 0)::int)) / cf.ct AS freeFROM (SELECt count(*)::float AS ct FROM applications WHERe price > 0) AS cc ,(SELECt count(*)::float AS ct FROM applications WHERe price = 0) AS cf ,permissions pLEFT JOIN applications_permissions ap ON ap.permission_id = p.idLEFT JOIN applications a ON a.id = ap.application_idGROUP BY 1, cc.ct, cf.ctORDER BY 2 DESC, 3 DESC, 1;
假设您的价格实际上是一个数字列-
0而不是
'0'。
这包括
permissions完全没有附加
applications的(
LEFT JOIN)。
如果可能
applications有未附加
permissions的列表,则这些列表的总和不会达到100%。
我只进行
ct一次总计数(),并将其转换
float为子查询中的值。其余的计算可以使用整数算术完成,只有最后一个
/ct将数字转换为浮点数。这是最快,最精确的。
与CTE相同
如果您愿意接受更多新东西:尝试使用CTE(公用表表达式-
WITH查询)
-从PostgreSQL 8.4开始可用。
它更干净,而且可能稍微快一点,因为我都在一个CTE中工作,而且价格便宜
GROUP BY-两者都可以通过子查询来完成:
WITH c AS ( SELECt sum((a.price > 0)::int) AS cc ,sum((a.price = 0)::int) AS cf FROM applications ), p AS ( SELECt id ,sum((a.price > 0)::int) AS pc ,sum((a.price = 0)::int) AS pf FROM permissions p LEFT JOIN applications_permissions ap ON ap.permission_id = p.id LEFT JOIN applications a ON a.id = ap.application_id GROUP BY 1 )SELECt p.id ,(100 * pc) / cc::float AS commercial ,(100 * pf) / cf::float AS freeFROM c, pORDER BY 2 DESC, 3 DESC, 1;



