具有多个连接的SQL查询(并存在?)

时间:2015-07-06 20:11:50

标签: sql sql-server join

我有一个SQL查询,我从表User,UserDetails和UserData获取数据。 我还必须检查表ConditionCheck,以获取此特定用户的任何条目。该表可以为每个用户进行多个条件检查。 如果表ConditionCheck甚至包含一个2或3的条目,我不会返回任何用户数据。

我写了如下查询:

select A.Column1, A.Column2, B.Column1, isnull(D.Column1, '')
from User A  WITH (NOLOCK) 
inner join UserDetails B  WITH (NOLOCK) on(B.id = A.id)
left join UserData C  WITH (NOLOCK) on (C.uid = B.uid)
left join ConditionCheck CC  WITH (NOLOCK)  on(CC.S_id = B.S_id)
left outer join MoreData D  WITH (NOLOCK)  on (D.id = A.id)
where A.Column1 = 'ABC' and CC.T_id not in(2, 3)

如果用户在CC中有条目1,2,4,5的行,我不想因为条件2存在而返回用户详细信息。但是,如果用户存在2或3行以外的行,则此查询将返回用户详细信息。

3 个答案:

答案 0 :(得分:2)

正如您在标题中推测的那样,使用EXISTS执行此操作可能比使用ConditionCheck表的正确连接更好。即使您的WHERE子句正在执行您想要的操作,您仍然会遇到ConditionCheck表中具有多个记录的用户在结果集中多次出现的问题。尝试这样的事情:

select 
    A.Column1, 
    A.Column2, 
    B.Column1, 
    isnull(D.Column1, '')
from
    User A  WITH (NOLOCK) 
    inner join UserDetails B  WITH (NOLOCK) on(B.id = A.id)
    left join UserData C  WITH (NOLOCK) on (C.uid = B.uid)
    left outer join MoreData D  WITH (NOLOCK)  on (D.id = A.id)
where
    A.Column1 = 'ABC' and 
    not exists
    (
        select 1 
        from
            ConditionCheck CC with (nolock) 
        where
            CC.S_id = B.S_id and 
            CC.T_id in (2, 3)
    );

答案 1 :(得分:2)

您需要在查询中添加NOT EXISTS子句,并将LEFT JOIN移到ConditionalCheck表中,因为您实际上并未对数据执行任何操作:

Select      A.Column1, A.Column2, B.Column1, IsNull(D.Column1, '')
From        User            A  With (NoLock) 
Inner Join  UserDetails     B  With (NoLock)    On  (B.id = A.id)
Left Join   UserData        C  With (NoLock)    On  (C.uid = B.uid)
Left Join   MoreData        D  With (NoLock)    On  (D.id = A.id)
Where       A.Column1 = 'ABC' 
And Not Exists
(
    Select  *
    From    ConditionalCheck    CC
    Where   CC.S_id = B.S_id
    And     CC.T_id In (2,3)
)

作为旁注,对于所提供查询的上下文, UserData 表的LEFT JOIN也是不必要的。

答案 2 :(得分:2)

由于您已经有一个左连接而您没有使用它,您可以通过更改您的连接以包含IN(2,3)并在cc上添加空检查来使用和反连接。

SELECT A.column1, 
       A.column2, 
       B.column1, 
       Isnull(D.column1, '') 
FROM   USER A WITH (nolock) 
       INNER JOIN userdetails B WITH (nolock) 
               ON( B.id = A.id ) 
       LEFT JOIN userdata C WITH (nolock) 
              ON ( C.uid = B.uid ) 
       LEFT JOIN conditioncheck CC WITH (nolock) 
              ON( CC.s_id = B.s_id 
                  AND CC.t_id IN( 2, 3 ) ) 
       LEFT OUTER JOIN moredata D WITH (nolock) 
                    ON ( D.id = A.id ) 
WHERE  A.column1 = 'ABC' 
       AND cc.s_id IS NULL 

您还可以使用not exists(其他答案)not in<> ALLEXCEPT

此外,NoLock连接提示允许返回不一致的数据。你确定要这么做吗?