简体   繁体   English

按同一个连接表过滤时计算所有连接表行

[英]Count all joined table rows when filtering by the same joined table

So I'm querying a table districts, that has one to many relationship with the positions table.所以我正在查询一个表区,它与位置表有一对多的关系。 I want to select the districts that have the positions with particular name AND count ALL districts positions at the same time.我想选择具有特定名称职位的地区并同时计算所有地区职位。 Can I do this?我可以这样做吗?

With the current code使用当前代码

 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

If I have 20 positions in some district but only 2 are filtered, positions_count eq 2 as well, I want it to be 20如果我在某个地区有 20 个职位,但只有 2 个被过滤,则 position_count eq 2 也是如此,我希望它是 20

I've tried to join twice on the same table with an alias but this gives me the same result我试图用别名在同一张桌子上加入两次,但这给了我相同的结果

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

I think you just want conditional aggregation:我认为你只想要条件聚合:

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;

Note: If you do not have duplicates for a given district, then there is no need to use COUNT(DISTINCT) , just COUNT() suffices.注意:如果给定地区没有重复项,则无需使用COUNT(DISTINCT) ,只需COUNT()就足够了。

Use the filtered positions to get the districts that you want in the results and then join all the positions:使用过滤后的位置在结果中得到你想要的区,然后加入所有位置:

SELECT d.*, 
  COUNT(DISTINCT p.id) as positions_count
FROM (
  SELECT DISTINCT d.* 
  FROM districts AS d INNER JOIN positions AS p 
  ON p.id = d.position_id
  WHERE p.name IN ($1, $2)
) AS d INNER JOIN positions AS p
ON p.id = d.position_id
GROUP BY d.id 
ORDER BY positions_count DESC, d.name ASC

I'm not sure about DISTINCT p.id .我不确定DISTINCT p.id You can also try without DISTINCT .您也可以尝试不使用DISTINCT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM