Объединение нескольких таблиц, выбор значений из разных таблиц и групп по одному столбцу в одном запросе

Мне нужно объединить несколько таблиц, выбрать подсчеты из разных таблиц и группу по одному столбцу в одном запросе. Вот как я буду делать это отдельно:

select      c.CommunityName, SUM(case when m.ListKey = c.ListKey then 1 else 0 end) as Posts
from        Community c with(NOLOCK)
join        messages_ m with(NOLOCK)
on          c.ListKey = m.ListKey
group by    c.CommunityName

select      c.CommunityName, SUM(case when b.CommunityKey = c.CommunityKey then 1 else 0 end) as Blogs
from        Community c with(NOLOCK)
join        Blog b with(NOLOCK)
on          c.CommunityKey = b.CommunityKey
group by    c.CommunityName

select      c.CommunityName, SUM(case when ce.CommunityKey = c.CommunityKey then 1 else 0 end) as Events
from        Community c with(NOLOCK)
join        CalendarEvent ce with(NOLOCK)
on          c.CommunityKey = ce.CommunityKey
where       ce.StartDateTime >= GETDATE()
group by    c.CommunityName

или просто

select      c.CommunityName, COUNT(*)
from        Community c with(NOLOCK)
join        messages_ m with(NOLOCK)
on          c.ListKey = m.ListKey
group by    c.CommunityName

select      c.CommunityName, COUNT(*)
from        Community c with(NOLOCK)
join        Blog b with(NOLOCK)
on          c.CommunityKey = b.CommunityKey
group by    c.CommunityName

select      c.CommunityName, COUNT(*)
from        Community c with(NOLOCK)
join        CalendarEvent ce with(NOLOCK)
on          c.CommunityKey = ce.CommunityKey
where       ce.StartDateTime >= GETDATE()
group by    c.CommunityName

Есть больше таблиц, некоторые из которых требуют дополнительных объединений... Может кто-то может помочь?

Ответ 1

Если я правильно понимаю ваш вопрос, вы ищете имя сообщества вместе со счетами, такими как сообщения, блоги, события и т.д.

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

SELECT CommunityName , SUM(MessageCount), SUM(BlogCount), SUM(EventCount)
FROM (
    SELECT      c.CommunityName CommunityName , COUNT(*) MessageCount, 0 BlogCount, 0 EventCount
    FROM        Community c with(NOLOCK)
    JOIN        messages_ m with(NOLOCK)
    ON          c.ListKey = m.ListKey
    GROUP BY    c.CommunityName

    UNION

    SELECT      c.CommunityName, 0, COUNT(*), 0
    FROM        Community c with(NOLOCK)
    JOIN        Blog b with(NOLOCK)
    ON          c.CommunityKey = b.CommunityKey
    GROUP BY    c.CommunityName

    UNION

    SELECT      c.CommunityName, 0, 0, COUNT(*)
    FROM        Community c with(NOLOCK)
    JOIN        CalendarEvent ce with(NOLOCK)
    ON          c.CommunityKey = ce.CommunityKey
    WHERE       ce.StartDateTime >= GETDATE()
    GROUP BY    c.CommunityName
  ) CountsTable
GROUP BY CountsTable.CommunityName

CountsTable будет выглядеть как

| COMMUNITYNAME | MESSAGECOUNT | BLOGCOUNT | EVENTCOUNT |
|---------------|--------------|-----------|------------|
|          Name |           10 |         0 |          0 |
|          Name |            0 |        20 |          0 |
|          Name |            0 |         0 |         30 |

Итак, вы можете GROUP BY назвать и суммировать подсчеты, чтобы получить результат

| COMMUNITYNAME | MESSAGECOUNT | BLOGCOUNT | EVENTCOUNT |
|---------------|--------------|-----------|------------|
|          Name |           10 |        20 |         30 |

Ответ 2

Задумывались ли вы об использовании LEFT JOIN для подключения таблиц? Затем вы можете проверить NULL и суммировать значения, отличные от NULL.

SELECT
    c.CommunityName,
    SUM(case when m.ListKey IS NOT NULL then 1 else 0 end) as Posts,
    SUM(case when b.CommunityKey IS NOT NULL then 1 else 0 end) as Blogs,
    SUM(case when ce.CommunityKey IS NOT NULL then 1 else 0 end) as Events
FROM
    Community c WITH(NOLOCK)
        LEFT JOIN
    messages_ m WITH(NOLOCK)
        ON c.ListKey = m.ListKey
        LEFT JOIN
    Blog b WITH(NOLOCK)
        ON c.CommunityKey = b.CommunityKey
        LEFT JOIN
    CalendarEvent ce WITH(NOLOCK)
        ON c.CommunityKey = ce.CommunityKey
WHERE
    ce.StartDateTime >= GETDATE()
GROUP BY
    c.CommunityName