2017-07-06 1 views
1

user tableSQL immer die richtigen Daten-Set mit Aggregat Abfrage

calls table

sms

, so habe ich den Benutzer, Anrufe, SMS-Tabelle, jetzt will ich die Anzahl der eingehenden und ausgehenden Anrufe bekommen und SMS pro Benutzer

ich habe diese Abfrage

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; 

und das Ergebnis ist diese

enter image description here

ankommende und abgehende in Anrufen korrekt ist, aber das Ergebnis ist falsch in Benutzer Probe in sms, sollte es 1 in Spalte sms und nicht 4

+0

Vereinfachen Sie die Abfrage deb ug, entferne die Gruppe mit und summiere und sieh nach, ob das Ergebnis korrekt ist. Ich glaube, es gibt ein Problem in der "Join", so dass es mehr "SMS" produziert. –

+0

Ich kann die Summe nicht entfernen, da ich die Anzahl der eingehenden und ausgehenden Anrufe benötige und wenn ich die Gruppe lösche, gibt es mir eine Zeile für den Beispielbenutzer –

+0

Welcher [DBMS] (https://en.wikipedia.org/wiki/DBMS) verwendest du? –

Antwort

1

zu vermeiden, dass der Multiplikationseffekt Sie mit den Verbindungsstellen haben, können Sie versuchen, die Anrufe und SMS-Tabellen separat vom User aggregieren, und dann auf diesen Subqueries Beitritt:

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

Vielen Dank dafür ist es ein bisschen lang Abfrage gibt es eine Möglichkeit, diese zu verkürzen? –

+0

@vladawtsu Ich kann mir keine einfachere Lösung vorstellen, die Ihnen die gewünschten Ergebnisse liefert. Ich denke nicht, dass es einfach funktionieren wird, alles so zu verbinden, wie Sie es ursprünglich versucht haben, wie Sie bereits gesehen haben. –

+0

immer noch danke :) –