左连接和有条件的地方没有给出预期的结果?
Left Join and conditional where not giving desired result?
我不知道怎么回答这个问题。但是请阅读说明。
我有两个 table 如下,
EntityProgress table-
EntityID CurrentStateID
101 1154
201 1155
301 1155
EnityApprovar Table
EntityID StateID ActorID
201 1154 8
201 1154 9
201 1155 8
301 1154 8
301 1154 9
301 1155 9
现在我想要的是,如果我将 ActorID=2
作为参数传递,那么它应该 return 只有一行,如下所示,因为我们在 entityapprovar
table。
EntityID CurrentStateID
101 1154
但是如果我通过 ActorID=9
那么它应该给我如下结果,
EntityID CurrentStateID
301 1155
因为我们在 EntityApprover
table 中有 entityID 匹配记录,而且对于那个 entityID,我们有 currentstateID,为此我们有 actorid 为 9。
所以为了得到我所做的结果,
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))
BUt 当我通过 2 时,我得到了第一个结果,但是当我通过 9/8 时,我没有得到想要的结果。可能这很简单,但我坚持下去。我需要一些其他人的观点来给我不同的方式。
如果出现混淆,请随时发表评论。
您必须在查询中包含一个 not exists
,因为您在传入 9 时试图排除的行没有信息来确定 table 中还有其他行那场比赛。
即
SELECT
E.EntityID,
E.CurrentStateID
FROM
EntityProgress E LEFT JOIN EnityApprovar EP
ON E.EntityID = EP.EntityID AND E.CurrentStateID = EP.StateID
WHERE ((ISNULL(EP.ActorID,0) = 0
and not exists(select 1
from EnityApprovar ep2
where ep2.ActorID = @ActorID ))
OR (ISNULL(EP.ActorID,0) != 0
AND EP.ActorID = @ActorID
AND E.CurrentStateID = Ep.StateID))
您对 ActorId 的查找 table 应该是查询的起点。如果您的模式中有 none(我对此表示怀疑),您可以尝试以此为起点。使用 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
当你通过 @ActorID = 9
然后它会给出下面的输出。
EntityID CurrentStateID
301 1155
如您所愿。
我不知道怎么回答这个问题。但是请阅读说明。 我有两个 table 如下,
EntityProgress table-
EntityID CurrentStateID
101 1154
201 1155
301 1155
EnityApprovar Table
EntityID StateID ActorID
201 1154 8
201 1154 9
201 1155 8
301 1154 8
301 1154 9
301 1155 9
现在我想要的是,如果我将 ActorID=2
作为参数传递,那么它应该 return 只有一行,如下所示,因为我们在 entityapprovar
table。
EntityID CurrentStateID
101 1154
但是如果我通过 ActorID=9
那么它应该给我如下结果,
EntityID CurrentStateID
301 1155
因为我们在 EntityApprover
table 中有 entityID 匹配记录,而且对于那个 entityID,我们有 currentstateID,为此我们有 actorid 为 9。
所以为了得到我所做的结果,
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))
BUt 当我通过 2 时,我得到了第一个结果,但是当我通过 9/8 时,我没有得到想要的结果。可能这很简单,但我坚持下去。我需要一些其他人的观点来给我不同的方式。 如果出现混淆,请随时发表评论。
您必须在查询中包含一个 not exists
,因为您在传入 9 时试图排除的行没有信息来确定 table 中还有其他行那场比赛。
即
SELECT
E.EntityID,
E.CurrentStateID
FROM
EntityProgress E LEFT JOIN EnityApprovar EP
ON E.EntityID = EP.EntityID AND E.CurrentStateID = EP.StateID
WHERE ((ISNULL(EP.ActorID,0) = 0
and not exists(select 1
from EnityApprovar ep2
where ep2.ActorID = @ActorID ))
OR (ISNULL(EP.ActorID,0) != 0
AND EP.ActorID = @ActorID
AND E.CurrentStateID = Ep.StateID))
您对 ActorId 的查找 table 应该是查询的起点。如果您的模式中有 none(我对此表示怀疑),您可以尝试以此为起点。使用 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
当你通过 @ActorID = 9
然后它会给出下面的输出。
EntityID CurrentStateID
301 1155
如您所愿。