Возврат всех результатов внешнего запроса и получение количества вложенных элементов. - PullRequest
0 голосов
/ 03 июня 2018

Поэтому я изо всех сил пытаюсь написать запрос, который возвращает мне все категории независимо от того, какой фильтр я применил, но количество изменений изменяется в зависимости от того, сколько будет возвращено рецептов в этом фильтре.

Этот запрос работает хорошо, если я не применяю к нему никаких фильтров.Счет кажется правильным, но как только я добавляю что-то вроде этого: 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 ]

0 голосов
/ 03 июня 2018

Нет необходимости во вложенном объединении, если вы переместите условие в обычное внешнее объединение:

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 в условие left join .Если оставить его в предложении where, эффект left
будет отменен.
0 голосов
/ 03 июня 2018

Я полагаю, что вы хотите:

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 s для всех объединений.
  • Агрегирует по всемнеагрегированные столбцы.
  • Он учитывает совпадающие рецепты, а не все строки.
  • Условие для рецептов перемещено в предложение on из предложения where.
0 голосов
/ 03 июня 2018

Просто используйте условное агрегирование, перемещая предложение WHERE в оператор CASE (или IF() для MySQL), заключенный в SUM() из 1 и 0 (то есть, счетчиков).Кроме того, обязательно последовательно используйте явное соединение, текущую отраслевую практику в SQL.В то время как ваша производная таблица использует эту форму соединения, внешний запрос использует идентификаторы неявного соединения, указанные в предложении WHERE.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...