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的