为什么我的LEFT JOIN不起作用?

时间:2018-06-19 21:40:35

标签: sql sql-server left-join ssms

目标是如果一个人在表PlayerToWar中没有包含@WarID和其PlayerID的行,则将Inactivity int增加50。

这是我目前拥有的脚本

Path
Filter
Include
Exclude
Force
Credential
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable

我想这样做是将dbo.Players中所有但不存在于SELECT语句中的所有人员的Inactivity列添加50,然后将其状态设置为已处理,以便脚本的其余部分不影响他们。

这是我发现的唯一方法。

4 个答案:

答案 0 :(得分:4)

尽管您可以使用left join,但not exists似乎是您逻辑的更清晰实现:

update P
    set Inactivity = p.Inactivity + 50,
        Processed = 1
    from dbo.Players  P
    where not exists (select
                      from dbo.PlayerToWar ptw
                      where ptw.PlayerID = p.PlayerId and ptw.WarID = @WarID
                     ) and
          p.Processed = 0;

这还解决了查询中的= NULL问题。

答案 1 :(得分:1)

您必须使用IS NULL而不是= NULL,我相信检查应该在X.PlayerId而不是P.PlayerId上

UPDATE P
SET P.Inactivity = P.Inactivity + 50,
    P.Processed = 1
FROM dbo.Players as P
LEFT JOIN ( SELECT PlayerID
            FROM dbo.PlayerToWar
            WHERE WarID = @WarID
            ) X
ON P.PlayerID = X.PlayerID
WHERE X.PlayerID IS NULL and P.Processed = 0

答案 2 :(得分:1)

UPDATE P
SET P.Inactivity = P.Inactivity + 50,
    P.Processed = 1
FROM dbo.Players as P
LEFT JOIN 
  dbo.PlayerToWar x      
ON P.PlayerID = x.PlayerID and x. WarID = @WarID   
WHERE x.PlayerID IS NULL and P.Processed = 0

个人首选项,但是IMO,最好不要将子查询放在括号内。原始查询永远不会取得任何结果,因为(大概)玩家表中的数据不允许使用空的PlayerID。

答案 3 :(得分:1)

where子句应具有x.playerID为null。同样,P.Processed = 1应该在join语句中。

UPDATE P
SET P.Inactivity = P.Inactivity + 50,
    P.Processed = 1
FROM dbo.Players as P
LEFT JOIN ( SELECT PlayerID
            FROM dbo.PlayerToWar
            WHERE WarID = @WarID
            ) X
ON P.PlayerID = X.PlayerID
and P.Processed = 0
WHERE X.PlayerID is NULL