Запрос на присоединение для подсчета количества записей не считается правильным - PullRequest
0 голосов
/ 09 декабря 2011

У меня есть таблица категорий, которая работает как теги в StackOverflow. Существуют такие категории, как JavaScript, который будет главной категорией, и, возможно, jQuery, который будет подкатегорией JavaScript.

Я пытаюсь запросить, сколько записей (в моем приложении это «проблемы») под каждой категорией.

Вот SQL, который у меня есть. Problem_categories - это просто объединяющая таблица, у которой есть problem_id и category_id.

select problems.problem_id , categories.category_id , category_name , count(problems.problem_id) as num_problems , is_top
from problems 
    left join problem_categories on
    problems.problem_id = problem_categories.category_id
    left join categories on
    problem_categories.category_id = categories.category_id
    where is_top = 1;

Возвращает только одну строку. Я надеялся, что верну количество записей, где is_top = 1 (это будет означать, что это высшая категория).

Как я могу изменить свой запрос, чтобы сделать это?

Спасибо !!

Ответы [ 3 ]

1 голос
/ 09 декабря 2011

"Это возвращает только одну строку. То, на что я надеялся, это вернуть количество записей, где is_top = 1 (это будет означать, что это верхняя категория)."Я подозреваю, что это то, что вы получаете.

...count(problems.problem_id) as num_problems...
...where is_top = 1;

Я думаю, вам нужно ввести предложение GROUP BY в одно или несколько полей

1 голос
/ 09 декабря 2011

Не догадываясь о логике, неправильно то, что вам нужно GROUP BY для подсчета:

SELECT problems.problem_id, categories.category_id, category_name, 
COUNT(problems.problem_id) as num_problems, is_top
FROM problems 
LEFT JOIN problem_categories 
ON problems.problem_id = problem_categories.category_id
LEFT JOIN categories 
ON problem_categories.category_id = categories.category_id
WHERE is_top = 1;
GROUP BY  problems.problem_id, categories.category_id, category_name

Но если вам нужно количество проблем на верхнюю категорию, ваша логика, вероятно, выглядит следующим образом:

SELECT category_name, categories.category_id, problems.problem_id, 
COUNT(problems.problem_id) as num_problems
FROM categories 
JOIN problem_categories 
ON problem_categories.category_id = categories.category_id
JOIN problems 
ON problems.problem_id = problem_categories.category_id
WHERE is_top = 1;
GROUP BY category_name, categories.category_id, problems.problem_id

Обратите внимание, что:

  • Для каждой категории вы получаете проблемы, и вместо этого вы их учитываете
  • Вы используете JOIN вместо LEFT JOIN, поскольку вам все равно, какие категории не имеют проблем.
  • Вы можете оставить is_top вне выбора, так как в любом случае вы помещаете его в предложение WHERE. Выбор чего-то, чего нет в вашем GROUP BY, получит любое случайное значение, но, поскольку все значения равны 1, вы можете спокойно это сделать или просто оставить это.
0 голосов
/ 09 декабря 2011

В вашем запросе есть несколько ошибок:

  1. Как упоминалось в других ответах, в запросе отсутствует предложение GROUP BY

  2. Первый JOIN в вашем запросе сопоставляет несвязанные столбцы - "on problem.problem_id = problem_categories.category_id". Как вы можете видеть, он объединяет problem_id с category_id

  3. Хотя это может быть не проблемой с текущим набором данных, но чтобы получить счетчики по категориям, имеет смысл держать таблицу categories в крайнем левом углу в левом соединении
  4. С точки зрения оптимизации, я не думаю, что вам нужно помещать таблицу problems в ваш запрос, потому что в этой таблице нет ничего, что нужно для вывода

Пожалуйста, под другой версией вашего запроса:

SELECT `categories`.`category_id`, `categories`.`category_name`, COUNT(`problem_categories`.`problem_id`) AS `num_problems`, `categories`.`is_top`
FROM `categories`
LEFT JOIN `problem_categories` ON `problem_categories`.`category_id` = `categories`.`category_id`
WHERE `categories`.`is_top` = 1
GROUP BY `categories`.`category_id`;

Надеюсь, что выше поможет!

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