この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

回答:


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

2つのパフォーマンスの違いは何ですか?結合はin(...)やin(...)を使用するよりもはるかに高速だと思いますが、exists(...)について考えたことはありませんか?
kacalapy 2011

結合にすべてのものを含めることもできます。質問の最後にある私の編集を参照してください
kacalapy

1
私が述べたように、WHERE句が必要です。
エリックハンフリー-lotsahelp

4
「はるかに速く実行する」?存在しないか、存在しないか?ない場合は、はい。存在しない場合、かなり同等です。
GBN、2011

1
またはSO
gbn 2011

7

ほとんどの場合、NOT EXISTSの方が効率的です。

LEFT JOINは、すべての行を内部的に照合し、IS NULLにフィルタリングします。存在しません。この行の乗算はすべてのJOINベースのコードでも発生するため、出力を修正するために追加の集計(DISTINCT)が必要になる場合があります

NULLは一致しないため、NOT INは一般的に間違っています。

また、NOT EXISTSと同じプランを提供するEXCEPTを使用することもできます。

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ビットは無視されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.