Есть такой запрос
SELECT category.name, COUNT(*) AS num_q FROM category, question WHERE question.cat_id = category.id GROUP BY category.name
Он выводит только те разделы и количество статей, в которых есть статьи, если статей нету, то категория вообще не выводится.
Как сделать так, что бы выводились все разделы и если в этом разделе пусто, то выводился 0?
Это делается с помощью LEFT OUTER JOIN.
Если запись для правой таблицы в частях ON или USING в LEFT OUTER JOIN не найдена, то для данной таблицы используется строка, в которой все столбцы установлены в NULL. Эту возможность можно применять для нахождения результатов в таблице, не имеющей эквивалента в другой таблице:
COUNT(q.cat_id) Показывает количество question для каждой category.
SELECT c.name, COUNT(q.cat_id) AS num_q
FROM category c
LEFT OUTER JOIN question q
on q.cat_id = c.id
GROUP BY c.name
Если вам нужно выбрать не повторяющиеся категории то сгруппируйте по их id:
Замените GROUP BY c.name на GROUP BY c.id.
Пред category и question буквы c и q называются алиасами.
Это не MySQL-специфичная фича, это элемент языка SQL. Служит для того, чтобы к таблице в пределах данного SQL-запроса можно было обращаться по другому имени. Обычно применяется:
а) в целях повышения читаемости запросов
б) в целях многократного использования одной и той же таблицы в одном запросе.
в) для именования подзапросов (в MySQL это обязательно, в отличие от других СУБД).
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники