如何用连接替换这个 where 子句?

kac*_*apy 8 sql-server-2005 sql-server except

通常,当我看到使用以下内容的 SQL 时:

select * from employees where epmloyeeTypeId in (select id from type where name = 'emp') 
Run Code Online (Sandbox Code Playgroud)

where用这个替换:

select e.* from employees e 
inner join type t on t.id=e.epmloyeeTypeId and t.name = 'emp'
Run Code Online (Sandbox Code Playgroud)

如果它是一个not in(如下所示)而不是一个in子句,是否可以对逆做同样的事情?

INSERT into Subscriptions(ProjectId, RecordTypeCID, NTID, Active, Added, LastUpdate, UpdateBy)   
 SELECT @ProjectId, RecordTypeCID, @NTID, 1, GETDATE(), GETDATE(), @NTID  
 FROM @Check CHK  
 WHERE CHK.ActiveStatus=1  
        And Not Exists (SELECT SubscriptionId FROM Subscriptions  
                        WHERE ProjectId=@ProjectId           
                        and NTID=@NTID          
                        and RecordTypeCID = CHK.RecordTypeCID
                        )  
Run Code Online (Sandbox Code Playgroud)

其他注意事项

我可以这样做吗:

INSERT INTO Subscriptions(ProjectId, RecordTypeCID, NTID,Active, Added, LastUpdate, UpdateBy)   
SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
    LEFT JOIN Subscriptions subs ON subs.RecordTypeCID = CHK.RecordTypeCID
        AND NTID = @NTID
        AND ProjectId = @ProjectId

        AND CHK.ActiveStatus = 1
        AND subs.SubscriptionId IS NULL
Run Code Online (Sandbox Code Playgroud)

gbn*_*gbn 7

在大多数情况下,您的 NOT EXISTS 更有效。

LEFT JOIN 在内部匹配所有行,然后过滤为 IS NULL。NOT EXISTS 不存在。此行乘法也发生在所有基于 JOIN 的代码中,因此您可能需要额外的聚合 (DISTINCT) 来修复输出

NOT IN 通常是错误的,因为 NULL 导致不匹配。

您还可以使用 EXCEPT,它提供与 NOT EXISTS 相同的计划。

SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
EXCEPT
SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM Subscriptions
WHERE ProjectId=@ProjectId           
and NTID=@NTID          
Run Code Online (Sandbox Code Playgroud)

仅供参考,根据SQL-92 标准(第 191 页,案例 3a),忽略 EXISTS 的 SELECT 位。


Eri*_*elp 6

是的。您可以替换为 LEFT JOIN ... WHERE key IS NULL。执行速度要快得多。

INSERT INTO Subscriptions(
    ProjectId, RecordTypeCID, NTID,
    Active, Added, LastUpdate, UpdateBy)   
SELECT @ProjectId, RecordTypeCID, @NTID,
    1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
LEFT JOIN Subscriptions subs
    ON subs.RecordTypeCID = CHK.RecordTypeCID
        AND NTID = @NTID
        AND ProjectId = @ProjectId
WHERE CHK.ActiveStatus = 1
    AND subs.SubscriptionId IS NULL
Run Code Online (Sandbox Code Playgroud)

  • “执行得更快”?比不存在或不存在?如果不在,是的。如果不存在,则相当相等。 (4认同)