2016-08-28 35 views
1

我想統計每user已關閉多少個conversations,以及每個user已編寫多少個messages協會計數

一個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 

當我沒有加入消息時,它工作正常只是計算封閉的談話。加入郵件時,closedreplied列是完全相同的數字(對於兩者也是不正確的)

任何想法?

+0

是'計數(不同c.id)'? – Mike

+0

是否有一列表示消息具有「關閉」或「已回覆」狀態? –

+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

這不會被app_id和display_name分組。如果我爲這些添加一個組,那麼它也想要一個關閉和回覆的組,但這沒有意義 – Tarlen