2017-07-06 45 views
1

user tableSQL使用得到正確的數據集彙總查詢

calls table

sms

所以我有用戶,通話,短信表,現在我想呼入和呼出電話的數量和每個用戶短信

我有這個疑問

select u.username, 
     sum(case when c.type = 'incoming' then 1 else 0 end) as incoming, 
     sum(case when c.type = 'incoming' and status = 'true' then 1 else 0 end) as answered, 
     sum(case when c.type = 'outgoing' then 1 else 0 end) as outgoing, 
     sum(case when s.type = 'in' then 1 else 0 end) as sms 
from user u 
join 
     calls c 
     on u.id = c.user_id 
join 
     sms s 
     on u.id = s.user_id 

group by u.username; 

,其結果是這

enter image description here

傳入和在呼叫傳出的是正確的,但在SMS中的結果是錯誤的用戶樣品中,它應爲1列SMS而不是4

+0

簡化查詢到deb ug,刪除組並且總結並且看結果是否是正確的。我相信'join'存在一個問題,它會產生更多'sms'。 –

+0

我不能刪除總和,因爲我需要在呼叫中傳入和傳出的計數,當我通過它刪除組時,會給我一行樣本用戶 –

+0

其中[DBMS](https://en.wikipedia.org/wiki/DBMS)你在用嗎? –

回答

1

要爲避免您對連接所產生的乘法效果,您可以嘗試分別按用戶聚合調用表和短信表,然後加入以下子查詢:

SELECT 
    u.username, 
    COALESCE(t1.incoming, 0) AS incoming, 
    COALESCE(t1.answered, 0) AS answered, 
    COALESCE(t1.outgoing, 0) AS outgoing, 
    COALESCE(t2.sms, 0) AS sms 
FROM user u 
LEFT JOIN 
(
    SELECT 
     user_id, 
     SUM(CASE WHEN type = 'incoming' THEN 1 ELSE 0 END) AS incoming, 
     SUM(CASE WHEN c.type = 'incoming' AND status = 'true' 
       THEN 1 ELSE 0 END) AS answered, 
     SUM(CASE WHEN c.type = 'outgoing' THEN 1 ELSE 0 END) AS outgoing 
    FROM calls 
    GROUP BY user_id 
) t1 
    ON u.id = t1.user_id 
LEFT JOIN 
(
    SELECT 
     user_id, 
     SUM(CASE WHEN s.type = 'in' THEN 1 ELSE 0 END) AS sms 
    FROM sms 
    GROUP BY user_id 
) t2 
    ON u.id = t2.user_id 
+0

謝謝你這有點長查詢有沒有辦法縮短這一個? –

+0

@vladawtsu我想不出一個更簡單的解決方案,它會給你你想要的結果。正如你已經看到的那樣,我認爲簡單地加入你最初嘗試過的所有東西都是可行的。 –

+0

還是謝謝:) –