У меня есть три таблицы в моей базе данных. Центральная таблица в звездообразной схеме — посылки со столбцом PK, называемым id. Каждая отправляющая запись может иметь ноль или более строк в таблицах открывается.
sendings.id = opens.sending_id
Точно так же третья таблица, называемая clicks, имеет следующую связь с таблицей отправки (одна отправка может иметь ноль или более кликов):
sendings.id = clicks.sending_id
Обе таблицы открывается и клики имеют свой уникальный столбец идентификатора, который называется id.
То, что я хотел бы иметь в одном запросе, это количество всех связанных открытий и кликов для каждой отправки. Следующий запрос, похоже, не соответствует этому требованию.
select s.id,
count(o.id) as open_count,
count(c.id) as click_count
from sendings s
left join opens o on s.sending_id = o.sending_id
left join clicks c on s.sending_id = c.sending_id
group by s.id;






Простое решение — использовать count(distinct):
select s.id,
count(distinct o.id) as open_count,
count(distinct c.id) as click_count
from sendings s left join
opens o
on s.sending_id = o.sending_id left join
clicks c
on s.sending_id = c.sending_id
group by s.id;
count() просто подсчитывает количество не-NULL значений.
В общем, более производительное решение — это коррелированные подзапросы или агрегация перед join:
select s.id, o.open_count, c.click_count
from sendings s left join
(select o.sending_id, count(*) as open_count
from opens o
group by o.sending_id
) o
on s.sending_id = o.sending_id left join
(select c.sending_id, count(*) as click_count
from clicks c
group by c.sending_id
) c
on s.sending_id = c.sending_id;
Обратите внимание, что внешний group by в этом случае не обязателен.
@disasterkid . . . Если ваши подсчеты больше, чем вы можете сосчитать на руках, используйте второе решение.
О, спасибо тебе большое. Какое из двух решений вы бы выбрали? Сначала я не ошибся, но
distinctотсутствовал, и мне было интересно, почему я получаю одинаковые числа.