Подтвердить что ты не робот

Несколько счетчиков в одном запросе SQL

Я пытаюсь получить количество документов в 4 конкретных разделах, используя следующий код:

SELECT
    category.id
    , category.title
    , count(ts1.section_id) AS doc1
    , count(ts2.section_id) AS doc2
    , count(ts3.section_id) AS doc3
    , count(ts4.section_id) AS doc4
FROM
    category 
    LEFT JOIN category_link_section AS ts1
        ON (category.id = ts1.category_id AND ts1.section_id = 1)
    LEFT JOIN category_link_section AS ts2
        ON (category.id = ts2.category_id AND ts2.section_id = 2)
    LEFT JOIN category_link_section AS ts3
        ON (category.id = ts3.category_id AND ts3.section_id = 3)
    LEFT JOIN category_link_section AS ts4
        ON (category.id = ts4.category_id AND ts4.section_id = 4)
GROUP BY category.id, ts1.section_id, ts2.section_id, ts3.section_id, ts4.section_id

В "категории" таблицы были идентификаторы, заголовок и т.д. Таблица 'category_link_section' содержит ссылки id между category_id, section_id и doc_id.

Если счетчик равен 0 для любого столбца, он отображает 0 в этом столбце. Но если результат не равен 0, он показывает результат умножения всех результатов секции. Поэтому, если бы мои 4 столбца подсчета должны были возвращаться: 1, 2, 0, 3; на самом деле это будет 6, 6, 0, 6;

Если я использую этот следующий код для каждой конкретной категории, я получаю результаты, которые я хочу:

SELECT
    category.id
    , category.title
    , count(ts1.section_id) AS doc1
FROM
    category 
    LEFT JOIN category_link_section AS ts1
        ON (category.id = ts1.category_id AND ts1.section_id = 1)
GROUP BY category.id, ts1.section_id

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

Итак, мой вопрос: нужно ли мне перешагнуть и вызвать каждый раздел по очереди, построив таблицу вне SQL, или это можно сделать в одном запросе?

4b9b3361

Ответ 1

@VoteyDisciple answer находится на правильном пути, но его запрос нуждается в некоторых улучшениях:

SELECT c.id, c.title,
    SUM(ts1.section_id = 1) AS doc1,
    SUM(ts1.section_id = 2) AS doc2,
    SUM(ts1.section_id = 3) AS doc3,
    SUM(ts1.section_id = 4) AS doc4
FROM category AS c
  LEFT JOIN category_link_section AS ts1
    ON (c.id = ts1.category_id)
GROUP BY c.id;

Пояснения:

  • Выражения IF() избыточны, поскольку равенство уже возвращает 1 или 0.
  • Выведите ts1.section_id=1 из условия соединения или вы никогда не получите другие значения section_id.
  • Только группа c.id. Я предполагаю, что OP только хочет одну строку для каждой категории и столбцы для подсчета каждого значения section_id для соответствующей категории. Если запрос сгруппирован по c.id, ts1.section_id, тогда будет до четырех строк для каждой категории.
  • Переместить запятые в список выбора. Запястья, плавающие в начале строки, выглядят уродливыми.; -)

Ответ 2

Возможно, вы захотите попробовать что-то вроде этого:

SELECT
    category.id
    , category.title
    , SUM(IF(ts1.section_id = 1, 1, 0)) AS doc1
    , SUM(IF(ts1.section_id = 2, 1, 0)) AS doc2
    , SUM(IF(ts1.section_id = 3, 1, 0)) AS doc3
    , SUM(IF(ts1.section_id = 4, 1, 0)) AS doc4
FROM
    category 
    LEFT JOIN category_link_section AS ts1
        ON (category.id = ts1.category_id AND ts1.section_id = 1)
GROUP BY category.id, ts1.section_id