Sql server 带WHERE子句的Sql左外部联接
我有两张桌子: 请求: 请求状态: 并非每个请求都有RequestStatus中的记录 我需要表请求中的所有记录,StatusID=2时除外。requestID=8应该被过滤掉Sql server 带WHERE子句的Sql左外部联接,sql-server,Sql Server,我有两张桌子: 请求: 请求状态: 并非每个请求都有RequestStatus中的记录 我需要表请求中的所有记录,StatusID=2时除外。requestID=8应该被过滤掉 我使用LEFT-OUTER-JOIN从表请求接收记录,但是当我添加Where子句Where StatusID=1时,它当然不起作用。您需要使用这样的not IN查询语句 Select * From Request Where RequestID not in (Select RequestID F
我使用LEFT-OUTER-JOIN从表请求接收记录,但是当我添加Where子句Where StatusID=1时,它当然不起作用。您需要使用这样的not IN查询语句
Select *
From Request
Where RequestID not in
(Select RequestID
From RequestStatus
Where StatusID = 2)
或
答案很简单,使用left join,但对StatusId不同于2的行进行筛选,如下所示:
select *
from request r
left join requestStatus rs
on r.requestID = rs.requestID
where rs.StatusId <> 2 or rs.StatusId IS NULL
编辑:added或rs.StatusId为NULL附加条件,以包括requestStatus表中与request表中不匹配的行。将约束移动到on子句中
select *
from request r
left join requestStatus rs
on r.requestID = rs.requestID
--and status_id = 1
and status_id <> 2
发生在您身上的是首先执行外部联接。来自外部联接但没有匹配项的任何行的所有列中都将有空值。然后应用where子句,但由于1为null,它不会像您希望的那样工作
编辑:根据皮尤斯的评论修改了子句。试试这个
SELECT *
FROM Request R
LEFT JOIN RequestStatus RS ON R.RequestID = RS.RequestID
WHERE RS.StatusID <> 2 OR RS.RequestID IS NULL
这个答案假设您只需要请求表中的RequestId&Msg,其中RequestStatus表中没有该RequestId和StatusId为2的记录
对于使用此查询的具有多个RequestStatus记录的请求,与Left join相比,您也不会获得额外的记录
使用not exists子句比本文中的Except、not In、EXTER Apply等更快 选择r.RequestId,r.Msg 从请求r 不存在的地方 选择1 来自状态请求者 其中rs.StatusId=2 和rs.RequestId=r.RequestId
在SQL Server 2017中,您可以通过这种方式打开和关闭
SELECT * FROM Request
LEFT OUTER JOIN RequestStatus ON Request.RequestID = RequestStatus.RequestID
AND RequestStatus.StatusID <> 2
WHERE Request.RequestID IS NOT NULL
@Andrew,我需要表请求中的所有记录,StatusID=2时除外。requestID=8应被过滤掉。。还需要说什么?这就是为什么我删除了我的boneheaded注释:但是,这个解决方案仍然会破坏外部连接:不是我的,但将外部表放在where子句中会强制只包含非空行,并根据该筛选器进行检查。实际上,这将使外部联接变成内部联接,并且不再返回OP想要的行。@Andrew,感谢您的评论和修改,这使我重新考虑where子句。刚刚编辑了答案。Andrew的答案比我的更清晰。在本文中使用not exists子句比Except、not In、EXTER Apply等更快。我认为OP需要除statusID=2之外的所有行,而不仅仅是1,它不会过滤掉statusID=2的行。仅移除右侧。在另一个例子中,这对我来说非常有效。伟大的思想也适用于PostgreSQL。谢谢
select *
from request r
left join requestStatus rs
on r.requestID = rs.requestID
--and status_id = 1
and status_id <> 2
SELECT *
FROM Request R
LEFT JOIN RequestStatus RS ON R.RequestID = RS.RequestID
WHERE RS.StatusID <> 2 OR RS.RequestID IS NULL
SELECT * FROM Request
LEFT OUTER JOIN RequestStatus ON Request.RequestID = RequestStatus.RequestID
AND RequestStatus.StatusID <> 2
WHERE Request.RequestID IS NOT NULL