2017-05-23 20 views
1

私は2つのテーブルから '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 

しかし、結果は私が期待したものではありません。それは私に2番目の左の結合をした後に間違った数を私に与えている。場合によっては2倍の結果となり、同じ結果を表示します(スクリーンショットに添付)。 enter image description here

+0

あなたは、テーブルdbo.UserEmailsOpensの定義を表示することができます任意の質問がある場合は、私に教えてください? –

+0

サブクエリを使用して結合する前にカウントするか、またはテーブル結合前に一意にする値でパーティション化されたウィンドウ関数を使用してカウントする必要があります。 – xQbert

+0

わかりませんが、nullがカウントされている可能性があります。あなたはそれをしたいですか? –

答えて

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; 

あなたは

関連する問題