2009-08-13 2 views
12

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

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 

В таблице «категория» имела идентификатор, название и т.д. The table '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, или это можно сделать в одном запросе?

ответ

26

@ 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, тогда будет до четырех строк для каждой категории.
  • Переместите запятые в списке выбора. Запястья, плавающие в начале строки, выглядят уродливыми. ;-)
+0

Можете ли вы объяснить улучшение? – Thilo

+0

Пояснения добавлены. –

+0

Удивительный! Благодарю. Работает как шарм. :) Я все еще буду использовать запятые впереди. Помогает мне увидеть, где синтаксические ошибки. ;) Еще раз спасибо. – Das123

6

Вы можете попробовать что-то вроде этого:

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 
Смежные вопросы