Sql-Server

如何用連接替換這個 where 子句?

  • December 6, 2018

通常,當我看到使用類似以下內容的 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子句,是否可以對 inverse 做同樣的事情?

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

是的。您可以替換為 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

在大多數情況下,您的 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          

僅供參考,根據SQL-92 標準(第 191 頁,案例 3a),EXISTS 的 SELECT 位被忽略。

引用自:https://dba.stackexchange.com/questions/1215