Sql 左连接和条件连接在哪里没有给出期望的结果?
我不知道如何回答这个问题。但请阅读描述。 我有两张桌子,如下所示Sql 左连接和条件连接在哪里没有给出期望的结果?,sql,sql-server,join,where-clause,Sql,Sql Server,Join,Where Clause,我不知道如何回答这个问题。但请阅读描述。 我有两张桌子,如下所示 EntityID CurrentStateID 301 1155 SELECT E.EntityID, E.CurrentStateID FROM EntityProgress E LEFT JOIN EntityApprover EP ON E.EntityID = EP.EntityID AND E.CurrentSta
EntityID CurrentStateID
301 1155
SELECT
E.EntityID,
E.CurrentStateID
FROM
EntityProgress E LEFT JOIN EntityApprover EP
ON E.EntityID = EP.EntityID AND E.CurrentStateID = EP.StateID
WHERE
-- some conditions
AND ((ISNULL(EP.ActorID,0) )= 0
OR ((ISNULL(EP.ActorID,0))!= 0 AND EP.ActorID = @ActorID AND Ep.CurrentStateID = E.StateID))
整体进度表-
EntityID CurrentStateID
101 1154
201 1155
301 1155
EnityApprovar表
EntityID StateID ActorID
201 1154 8
201 1154 9
201 1155 8
301 1154 8
301 1154 9
301 1155 9
现在我想要的是,如果我将ActorID=2
作为参数传递,那么它应该只返回一行,如下所示,因为entityapprovar
表中没有任何匹配的enityID
EntityID CurrentStateID
101 1154
但是如果我通过了ActorID=9
,那么它应该给出如下结果
EntityID CurrentStateID
301 1155
SELECT
E.EntityID,
E.CurrentStateID
FROM
EntityProgress E LEFT JOIN EntityApprover EP
ON E.EntityID = EP.EntityID AND E.CurrentStateID = EP.StateID
WHERE
-- some conditions
AND ((ISNULL(EP.ActorID,0) )= 0
OR ((ISNULL(EP.ActorID,0))!= 0 AND EP.ActorID = @ActorID AND Ep.CurrentStateID = E.StateID))
因为我们在EntityApprover
表中有entityID匹配记录,而且对于该entityID,我们有currentstateID,对于该entityID,我们有actorid作为9
为了得到结果,我做了如下工作
EntityID CurrentStateID
301 1155
SELECT
E.EntityID,
E.CurrentStateID
FROM
EntityProgress E LEFT JOIN EntityApprover EP
ON E.EntityID = EP.EntityID AND E.CurrentStateID = EP.StateID
WHERE
-- some conditions
AND ((ISNULL(EP.ActorID,0) )= 0
OR ((ISNULL(EP.ActorID,0))!= 0 AND EP.ActorID = @ActorID AND Ep.CurrentStateID = E.StateID))
但是当我通过2分时,我得到了第一个结果,但是当我通过9/8分时,我没有得到想要的结果。也许这很简单,但我一直坚持着。我需要一些其他人的观点来给我不同的方式。
如果您感到困惑,请随时留下评论 您必须在查询中包含一个
not exists
,因为传入9时尝试排除的行没有确定表中是否有其他匹配行的信息
i、 e
ActorId的查找表应该是查询的起点。如果您的模式中没有(我对此表示怀疑),您可以尝试将此作为起点。使用T-SQL语法:
DECLARE @ActorID int
SET @ActorID = 2
SELECT * FROM
(SELECT @ActorID AS EntityId)
Actor
LEFT JOIN
EntityApprover EA
ON Actor.EntityId = EA.EntityId ...
您可以从中提取其他列的值。以下是我试图回答您的问题 查询
DECLARE @ActorID int = 2
DECLARE @EntityProgress table
(
EntityID int,
CurrentStateID int
)
DECLARE @EnityApprovar table
(
EntityID int,
StateID int,
ActorID int
)
INSERT into @EntityProgress
values (101, 1154),
(201, 1155),
(301, 1155)
INSERT into @EnityApprovar
VALUES (201, 1154, 8),
(201, 1154, 9),
(201, 1155, 8),
(301, 1154, 8),
(301, 1154, 9),
(301, 1155, 9)
SELECT
E.EntityID
,E.CurrentStateID
,EP.ActorID
FROM @EntityProgress E
LEFT JOIN @EnityApprovar EP
ON E.EntityID = EP.EntityID
AND E.CurrentStateID = EP.StateID
WHERE ((EP.ActorID IS NULL AND NOT EXISTS (SELECT 1 FROM @EnityApprovar WHERE ActorID = @ActorID))
OR (EP.ActorID = @ActorID))
当您传递@ActorID=2
时,它将给出以下输出
EntityID CurrentStateID
101 1154
EntityID CurrentStateID
301 1155
当您传递@ActorID=9
时,它将给出以下输出
EntityID CurrentStateID
101 1154
EntityID CurrentStateID
301 1155
这正是你想要的 左连接时,将右侧表的条件放在ON子句中,以获得真正的左连接行为。(在WHERE中,你得到了内部连接结果。)@jarlh我不明白你的意思。您能解释一下位或任何指针或链接吗?常规内部联接意味着返回两个表中满足ON子句的行。当左连接时,也会返回左侧表中不满足ON条件的行,这里为右侧表返回NULL。如果WHERE子句在这些空值上包含“regualar”条件,则WHERE将为false且不返回任何内容,即返回内部联接结果!但是,也许那些是空的,让我们来处理这个?(我不知道它们是如何工作的…@jarlh它返回给我一个真正的左连接结果,该结果带有空值。我在条件where中使用该结果来获得我想要的结果。没有给出所需的结果。而且,如果第一个条件为真,那么该表中该实体将没有记录,因此“不存在”在这种情况下可能不起作用。实际上,它确实给出了您问题中所述的2和9作为输入的预期结果。接受的答案使用了相同的逻辑,只是更加简化了。没有理由否决投票。这与所问的问题有什么关系。只是一个小小的改变:请用一个简单的
EP.ActorID is NULL(EP.ActorID,0)=0
替换OP的