如何用联接替换where子句?


8

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

select * from employees where epmloyeeTypeId in (select id from type where name = 'emp') 

我将其替换为where

select e.* from employees e 
inner join type t on t.id=e.epmloyeeTypeId and t.name = 'emp'

如果逆是子句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
                        )  

其他注意事项

我可以这样做吗?

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

Answers:


6

是。您可以用LEFT JOIN ... WHERE键为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

两者的性能有何不同?我认为联接比使用in(...)或不使用in(...)快得多,从来没有想过存在(...)任何想法?
kacalapy 2011年

我还可以在
联接中

1
如我所述,您必须具有WHERE子句。
埃里克·汉弗莱

4
“执行速度快得多”?是否不存在或不存在?如果不在,则为是。如果不存在,则相当。
gbn


7

在大多数情况下,您的“不存在”效率更高。

LEFT JOIN内部匹配所有行,然后过滤为IS NULL。不存在不存在。所有基于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          

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.