具有多个联接的SQL查询(是否存在?)
我有一个sql查询,其中我从User表、UserDetails表和UserData表中获取数据。 我还必须检查ConditionCheck表,以查找此特定用户的任何条目。此表可以对每个用户进行多个条件检查。 如果表ConditionCheck甚至包含一个2或3的条目,我不会返回任何用户数据 我编写了如下查询:具有多个联接的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
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子句中。它开始工作了。