2017-05-23 53 views
1

我有一個查詢,我需要從兩個表中計算'userID'。帶有計數和左連接的SQL查詢

SQL查詢:

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 

但是,結果是不是我所期待。在我進行第二次左連接之後,它給了我錯誤的數字。這是我在某些情況下的兩倍結果,並顯示相同的計數結果(附加屏幕截圖)。 enter image description here

+0

可以顯示錶dbo.UserEmailsOpens定義是什麼? –

+0

您必須在使用子查詢進行連接之前進行計數,或者使用窗口函數進行計數,該窗口函數使用在表連接之前使其具有唯一性的值進行分區。 – xQbert

+0

我不確定,但它可能正在計算空值。你想讓它做到嗎? –

回答

1

骨料的加入,像這樣前:

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

修改您的查詢了一下。使用Case When來消除結果中空白的計數。

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; 

讓我知道如果您有任何疑問