具有多个联接的SQL查询(是否存在?)

具有多个联接的SQL查询(是否存在?),sql,sql-server,join,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) inne

我有一个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行,则此查询将返回用户详细信息。

正如您在标题中推测的那样,使用
EXISTS
执行此操作可能比正确连接到
条件检查表要好。即使您的
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)
    );

正如您在标题中推测的,使用
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)
    );

您需要在查询中添加一个
NOT EXISTS
子句,并将
LEFT JOIN
删除到您的条件检查表中,因为您实际上没有对那里的数据执行任何操作:

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)
)

作为旁注,对于提供的查询上下文,用户数据表的
左连接也没有必要。

您需要向查询中添加
不存在
子句,并将
左连接
删除到您的条件检查表中,因为您实际上没有对那里的数据执行任何操作:

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)
)

作为旁注,对于所提供的查询上下文,用户数据表的
左连接也没有必要。

因为您已经有一个左连接,并且您没有使用它,您可以在这里使用和反连接,方法是将您的连接更改为在(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 
您还可以使用
不存在
(其他答案)
不在
所有


这些NoLock join提示还允许返回不一致的数据。你确定要这么做吗

由于您已经有一个左连接,而您没有使用它,您可以在此处使用和反连接,方法是将您的连接更改为在(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 
您还可以使用
不存在
(其他答案)
不在
所有


这些NoLock join提示还允许返回不一致的数据。你确定要这么做吗

您在查询中同时使用
left join
left outer join
的具体原因是什么?这并不重要,我只是好奇(如果你认为它们的表现会不同的话)。你在查询中同时使用
左连接
左外连接
有什么具体原因吗?这并不重要,我只是好奇(如果你认为他们的表现会不同的话)。我试过这个。但它不起作用。我有一个用户在CC中有两行,条件1和3。但此版本的查询仍将返回用户详细信息。它的工作原理与我之前的查询类似。我已经让它工作了。你是对的。联接中不需要表C。只有A、B和D应该在联接中。然后我将C和CC表放在notexists子句中。它开始起作用了,我试过了。但它不起作用。我有一个用户在CC中有两行,条件1和3。但此版本的查询仍将返回用户详细信息。它的工作原理与我之前的查询类似。我已经让它工作了。你是对的。联接中不需要表C。只有A、B和D应该在联接中。然后我将C和CC表放在notexists子句中。它开始工作了。