2016-08-28 2 views
1

Я хочу подсчитать, сколько conversations каждый user закрыл, и сколько messages написал каждый user.Подсчитайте количество ассоциаций

user имеет много conversations

conversations имеет много messages

message может принадлежать к user

Это запрос, я получил некоторые далеко

select a.id, u.display_name, count(c.id) as closed, count(m.id) as replied 
from apps a 
left join app_users au on au.app_id = a.id 
left join users u on u.id = au.user_id 
left join conversations c on c.app_id = a.id and c.closed_by_id = u.id 
left join messages m on m.conversation_id = c.id and m.user_id = u.id 
group by a.id, u.id 
order by closed desc 

Он отлично работает, когда я не присоединяюсь к сообщениям и просто считая закрытые разговоры. При подключении сообщений колонки closed и replied - это то же самое число (и также неверны для обоих)

Любые идеи?

+0

может быть 'граф (отличный c.id)'? – Mike

+0

есть столбец, в котором говорится, что сообщение имеет статус 'closed' или' reply'? –

+0

Нет, но есть 'closed_at', и пользователь ответил на сообщение, если' user_id' сообщения соответствует пользователю, который мы подсчитываем для – Tarlen

ответ

0

Быстрый и грязный раствор использовать count(distinct):

select a.id, u.display_name, 
     count(distinct c.id) as closed, count(distinct m.id) as replied 

Это будет работать при многих обстоятельствах. Но если есть много «закрытых» и «ответивших», то промежуточный расчет может быть довольно большим, что влияет на производительность. Если это проблема, то предварительная агрегирование результатов до объединения является решением.

1

Вы можете сделать подсчет в подзапросов до вступления:

select a.id, u.display_name, c.closed, m.replied 
from apps a 
left join app_users au on au.app_id = a.id 
left join users u on u.id = au.user_id 
left join lateral (
    select id, count(*) as closed 
    from conversations 
    where closed_by_id = u.id) c on c.app_id = a.id 
left join lateral (
    select count(*) as replied 
    from messages 
    where user_id = u.id) m on m.conversation_id = c.id 
order by c.closed desc; 
+0

. Это не group by app_id и display_name. Если я добавлю группу для них, тогда она также захочет создать группу для 'closed' и' reply', но это не имеет смысла – Tarlen

Смежные вопросы