返回外部查询的所有结果并获取附加项的计数

时间:2018-06-03 00:44:16

标签: mysql sql

所以我努力编写一个查询,无论我应用了什么过滤器,都会返回所有类别,但计数会根据此过滤器中返回的食谱数量而变化。

如果我不对其应用任何过滤器,则此查询很有效。计数似乎是正确的,但是一旦我添加这样的内容:where c.parent_id is not null and r.time_cook_minutes > 60我将过滤掉大多数类别而不是仅仅计数为零。

这是我提出的一个示例查询,它不能按照我想要的方式运行:

select t.id, t.name, t.parent_id, a.cntr from categories as t,
   (select c.id, count(*) as cntr from categories as c 
   inner join recipe_categories as rc on rc.category_id = c.id
   inner join recipes as r on r.id = rc.recipe_id 
   where c.parent_id is not null and r.time_cook_minutes > 60
   group by c.id) as a
where a.id = t.id
group by t.id

因此,正如您可能想象的那样,目前只返回此过滤器子集中存在的配方计数...我想要的是无论过滤器的计数是多少都得到所有这些,如果他们在该过滤器下没有任何食谱。

对此的任何帮助将不胜感激。如果这个问题不是很明确,请告诉我,我可以详细说明。

3 个答案:

答案 0 :(得分:3)

如果将条件移动到常规外部联接中,则不需要嵌套连接:

select t.id, t.name, t.parent_id, count(r.id)
from categories as t
left join recipe_categories as rc on rc.category_id = c.id
left join recipes as r on r.id = rc.recipe_id
   and r.time_cook_minutes > 60
where c.parent_id is not null
group by 1, 2, 3

注意:

  • 使用left加入,以便始终获得所有类别
  • r.time_cook_minutes > 60放在左连接条件下。将其留在where子句上会取消left
  • 的效果

答案 1 :(得分:1)

只需使用条件聚合,将WHERE子句移动到包含在CASE的1和0的IF()(或SUM() for MySQL)语句中(即计数) )。此外,请务必始终使用显式连接,即SQL中当前的行业惯例。虽然派生表使用这种形式的连接,但外部查询在WHERE子句中使用隐式连接匹配ID。

select t.id, t.name, t.parent_id, a.cntr 
from categories as t
inner join
   (select c.id, sum(case when c.parent_id is not null and r.time_cook_minutes > 60
                          then 1 
                          else 0
                     end) as cntr 
    from categories as c 
    inner join recipe_categories as rc on rc.category_id = c.id
    inner join recipes as r on r.id = rc.recipe_id 
    group by c.id) as a
on a.id = t.id
group by t.id

答案 2 :(得分:1)

我相信你想要:

select c.id, c.name, c.parent_id, count(r.id)
from categories c left join
     recipe_categories rc
     on rc.category_id = c.id left join
     recipes r
     on r.id = rc.recipe_id and r.time_cook_minutes > 60
where c.parent_id is not null and 
group by c.id, c.name, c.parent_id;

注意:

  • 这会将left join用于所有联接。
  • 它按所有非聚合列聚合。
  • 它会计算匹配的食谱而非所有行。
  • 配方的条件从on子句移到where子句。