Запрос количества перестал работать правильно после добавления предложения where - PullRequest
1 голос
/ 21 января 2012

У меня есть 3 таблицы: задачи, категории и объединяющая таблица для problem_categories

Я пытаюсь получить и подсчитать все категории, связанные с проблемой, и подсчитать, сколько проблем связано с каждой проблемой.

Вот мой запрос, который не возвращает правильные результаты:

SELECT 
  category_name , 
  categories.category_id , 
  problems.problem_id, 
  COUNT(problems.problem_id) as num_problems 
FROM 
  problem_categories 
left JOIN 
  categories 
on 
  problem_categories.category_id = categories.category_id 
left join 
  problems 
on
  problem_categories.problem_id = problems.problem_id 
WHERE 
  problem_categories.problem_id = 266
GROUP BY 
  problems.problem_id , category_name

но как только я уберу предложение where, оно возвращает все категории и правильное количество проблем. Но хитрость в том, что мне нужно запросить это для конкретной проблемы_id

Есть ли способ настроить этот запрос, чтобы он был правильным? Что я здесь делаю неправильно?

Спасибо !!

Ответы [ 4 ]

1 голос
/ 21 января 2012

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

SELECT categories.category_name ,
       categories.category_id,
       (select COUNT(*)
        from problem_categories
        where problem_categories.category_id =categories.category_id
       ) as num_problems
FROM categories 

, который можно использовать в объединении (и, если хотите, во временной таблице), чтобы дополнить информацию о категориях:

select problem_categories.problem_id,
       temp_tab.category_name ,
       temp_tab.category_id,
       temp_tab.num_problems            
from problem_categories, 
(
SELECT categories.category_name ,
       categories.category_id,
       (select COUNT(*)
        from problem_categories
        where problem_categories.category_id =categories.category_id
       ) as num_problems
FROM categories 
) temp_tab
where problem_categories.problem_id =266
and problem_categories.category_id = temp_tab.category_id

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

1 голос
/ 21 января 2012

Ваш вопрос несколько неясен. Как вы можете считать проблемы, если вы выбираете конкретную? Если вы хотите подсчитать категории, связанные с конкретной проблемой, вы делаете это (я предполагаю, что у вас есть внешние ключи и нет дубликатов в таблице problem_categories):

SELECT problem_id, COUNT(category_id) as num_categories
FROM problem_categories
WHERE problem_id = 266
GROUP BY problem_id

, затем присоединитесь к таблице проблем, если вам нужно распечатать больше информации о проблемах (для эффективности всегда подробно указывайте последние). Если вы хотите посчитать проблему -> категория -> проблема, то выполните:

select p1.problem_id, (COUNT(DISTINCT(p2.problem_id)) - 1) as num_problems
FROM
(select problem_id, category_id FROM problem_categories where problem_id = 266) as p1
inner join 
(select problem_id, category_id FROM problem_categories) as p2
ON p1.category_id = p2.category_id
GROUP by p1.problem_id

Опять же, если вы хотите показать подробности проблемы, присоединитесь к таблице проблем, чтобы получить их. Если вы хотите, чтобы num_problems и num_categories вместе соединяли первый запрос со вторым, прежде чем соединяться с таблицей проблем, чтобы получить подробности проблемы. i.e.:

SELECT p1.problem_id, p1.num_categories, p2.num_problems 
FROM
(SELECT problem_id, COUNT(category_id) as num_categories
FROM problem_categories
WHERE problem_id = 266
GROUP BY problem_id) as p1
INNER JOIN
(SELECT p1.problem_id, (COUNT(DISTINCT(p2.problem_id)) - 1) as num_problems
FROM
(SELECT problem_id, category_id FROM problem_categories where problem_id = 266) as p1
INNER JOIN 
(SELECT problem_id, category_id FROM problem_categories) as p2
ON p1.category_id = p2.category_id
GROUP by p1.problem_id) as p2
ON p1.problem_id = p2.problem_id
1 голос
/ 21 января 2012

Я думаю, что должно работать следующее:

SELECT category_name , categories.category_id, COUNT(*) as num_problems 
FROM problem_categories src JOIN CATEGORIES ON src.category_id = categories.category_id 
    JOIN problem_categories dest ON categories.category_id = dest.category_id 
WHERE problems.problem_id = 266
GROUP BY categories.category_id

То, что вы делаете, это для идентификатора проблемы, который вы хотите, вы ищите идентификаторы категорий и оттуда имена, а из идентификаторов категорий вы смотрите, сколько (если таковые имеются) проблемы у каждой. Неиспользование таблицы проблем является преднамеренным. Кроме того, для этого вам нужно проиндексировать проблемную категорию в ОБАХ заказах.

ОБНОВЛЕНИЕ: левое соединение может быть внутренним соединением, потому что каждая категория, связанная с проблемой 266, имеет по крайней мере одну проблему (проблема 266).

1 голос
/ 21 января 2012
SELECT p1.problem_id, problem_categories.category_id , category_name , 
    COUNT(*) as num_problems 
FROM problems p1
LEFT JOIN problem_categories  on
   p1.problem_id = problem_categories.problem_id 
LEFT JOIN categories on 
   problem_categories.category_id = categories.category_id 
LEFT JOIN problems p2 ON
   p2.problem_id = problem_categories.problem_id 
WHERE p1.problem_id = 266
GROUP BY categories.category_id,p2.problem_id
ORDER BY categories.category_id

Вот так

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...