首页 > 解决方案 > 按同一个联接表过滤时计算所有联接表行

问题描述

所以我正在查询一个表区,它与位置表具有一对多的关系。我想选择具有特定名称职位的地区并同时计算所有地区职位。我可以这样做吗?

使用当前代码

 SELECT districts.*, COUNT(DISTINCT(positions.id)) as positions_count FROM "districts"
  LEFT JOIN positions ON positions.id = districts.position_id
 WHERE ("positions"."name" IN ($1, $2)) GROUP BY districts.id ORDER BY positions_count desc, "districts"."name" ASC

如果我在某个地区有 20 个职位,但只有 2 个被过滤,positions_count eq 2 也是,我希望它是 20

我尝试使用别名在同一张桌子上加入两次,但这给了我相同的结果

SELECT districts.*, COUNT(DISTINCT(positions_to_count.id)) as positions_count FROM "districts"
  LEFT JOIN positions ON positions.id = districts.position_id
  LEFT JOIN positions AS positions_to_count ON positions_to_count.id = districts.position_id WHERE ("positions"."name" IN ($1, $2)) GROUP BY districts.id ORDER BY positions_count desc, "districts"."name" ASC

标签: sqlpostgresql

解决方案


我想你只想要条件聚合:

SELECT d.*, COUNT(DISTINCT p.id) as positions_count,
       COUNT(DISTINCT CASE WHEN p.name IN ($1, $2) THEN p.id END) as positions_name
FROM "districts" d LEFT JOIN
     positions p 
     ON p.id = d.position_id 
GROUP BY d.id
ORDER BY positions_count desc, d."name" ASC;

注意:如果您没有给定区域的重复项,则无需使用COUNT(DISTINCT),就COUNT()足够了。


推荐阅读