2017-05-23 1 views
1

Ich habe eine Abfrage, wo ich 'UserID' aus 2 Tabellen berechnen muss.SQL-Abfrage mit Anzahl und linken Join

SQL QUERY:

SELECT DISTINCT TOP 1000 u.id as userID, u.firstName as userFirstName, u.email as userEmail, u.phone as userPhone, 
count(ueo.userID) as opensEmailCounter, count(ush.userID) as opensSmsCounter 
    FROM dbo.Users u 
    LEFT JOIN dbo.UserEmailsOpens ueo ON u.id = ueo.userID AND ueo.targetID = 4 
    LEFT JOIN dbo.UserSmsHistory ush ON u.id = ush.userID AND ush.targetID = 4 AND ush.opened = 1 
    WHERE u.deleted = 0 
    AND IsNull(u.firstName, '') != '' 
    AND IsNull(u.email, '') != '' 
    AND IsNull(u.phone, '') != '' 
GROUP BY u.id, u.firstName, u.email, u.phone 

Aber das Ergebnis ist nicht das, was ich erwartet hatte. Es gibt mir die falschen Zahlen, nachdem ich den zweiten Link beigetreten bin. Es ist in einigen Fällen doppelt mein Ergebnis und zeigt das gleiche Zählergebnis (angehängt den Screenshot). enter image description here

+0

können Sie die Tabelle dbo.UserEmailsOpens Definition zeigen? –

+0

Sie müssen entweder vor dem Join mit einer Unterabfrage oder einer Anzahl zählen, indem Sie eine Fensterfunktion verwenden, die durch die Werte partitioniert wird, die sie vor dem Join der Tabelle eindeutig machen. – xQbert

+0

Ich bin mir nicht sicher, aber es könnte Nullen zählen. Willst du, dass es das tut? –

Antwort

1

Aggregate vor dem schließt sich in etwa so:

select distinct top 1000 
    u.id as userID 
    , u.firstName as userFirstName 
    , u.email as userEmail 
    , u.phone as userPhone 
    , ueo.opensEmailCounter 
    , ush.opensSmsCounter 
from dbo.Users u 
    left join (
    select 
     userID 
     , count(*) as opensEmailCounter 
    from dbo.UserEmailsOpens 
    where targetID = 4 
    group by userID 
    ) ueo 
    on u.id = ueo.userID 
    left join (
    select 
     userID 
     , count(*) as opensSmsCounter 
    from dbo.UserSmsHistory 
    where targetID = 4 
     and opened = 1 
    group by userID 
    ) ush 
    on u.id = ush.userID 
where u.deleted = 0 
    and IsNull(u.firstName, '') != '' 
    and IsNull(u.email, '')  != '' 
    and IsNull(u.phone, '')  != '' 
0

Verändert Ihre Abfrage ein bisschen. Verwendet Case When, um das Auszählen von Leerzeichen aus dem Ergebnis zu eliminieren.

Select userID, userFirstName, userEmail, userPhone, 
sum(case when ueo_userID <> '' then 1 else 0 end) as opensEmailCounter, 
sum(case when ush_userID <> '' then 1 else 0 end) as opensSmsCounter 
from 
(
    SELECT DISTINCT u.id as userID, u.firstName as userFirstName, u.email as userEmail, u.phone as userPhone, 
    ueo.userID as ueo_userID, ush.userID as ush_userID 
    FROM dbo.Users u 
    LEFT JOIN dbo.UserEmailsOpens ueo ON u.id = ueo.userID AND ueo.targetID = 4 
    LEFT JOIN dbo.UserSmsHistory ush ON u.id = ush.userID AND ush.targetID = 4 AND ush.opened = 1 
    WHERE u.deleted = 0user 
    AND IsNull(u.firstName, '') != '' 
    AND IsNull(u.email, '') != '' 
    AND IsNull(u.phone, '') != '' 
) a 
GROUP BY userID, userFirstName, userEmail, userPhone; 

Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben

Verwandte Themen