Sql-Server
如何用連接替換這個 where 子句?
通常,當我看到使用類似以下內容的 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 位被忽略。