所以我努力编写一个查询,无论我应用了什么过滤器,都会返回所有类别,但计数会根据此过滤器中返回的食谱数量而变化。
如果我不对其应用任何过滤器,则此查询很有效。计数似乎是正确的,但是一旦我添加这样的内容: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
因此,正如您可能想象的那样,目前只返回此过滤器子集中存在的配方计数...我想要的是无论过滤器的计数是多少都得到所有这些,如果他们在该过滤器下没有任何食谱。
对此的任何帮助将不胜感激。如果这个问题不是很明确,请告诉我,我可以详细说明。
答案 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
子句。