Bagaimana cara mengganti ini di mana klausa dengan bergabung?

8

Biasanya ketika saya melihat SQL yang menggunakan sesuatu seperti:

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

Saya ganti wheredengan ini:

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

Apakah mungkin untuk melakukan hal yang sama dengan invers jika ini adalah not in(seperti di bawah) daripada inklausa?

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
                        )  

Pertimbangan tambahan

Bisakah saya melakukan ini:

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
kacalapy
sumber

Jawaban:

6

Iya. Anda dapat mengganti dengan LEFT JOIN ... WHERE key IS NULL. Berperforma jauh lebih cepat.

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
Eric Humphrey - lotahelp
sumber
apa kinerja yang berbeda antara keduanya? Saya akan berpikir bergabung lebih cepat daripada menggunakan di (...) atau tidak di (...), tidak pernah memikirkan ada (...) ada ide?
kacalapy
juga dapat saya sertakan setiap hal dalam bergabung, lihat edit saya di bagian bawah pertanyaan
kacalapy
1
Anda harus memiliki klausa WHERE seperti yang saya nyatakan.
Eric Humphrey - lotsahelp
4
"Berkinerja lebih cepat"? Dari TIDAK ADA atau TIDAK DI? Jika TIDAK, ya. Jika BUKAN ADA, cukup sama.
gbn
1
Contoh atau SO
gbn
7

Anda TIDAK ADA lebih efisien dalam banyak kasus.

LEFT JOIN secara internal mencocokkan semua baris lalu memfilter ke IS NULL. BUKAN ADA tidak. Perkalian baris ini juga terjadi di semua kode berbasis GABUNG sehingga Anda mungkin memerlukan agregat tambahan (DISTINCT) untuk memperbaiki output

BUKAN DI umumnya salah karena NULL tidak menyebabkan kecocokan.

Anda juga dapat menggunakan KECUALI yang memberikan paket yang sama dengan BUKAN ADA.

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          

FYI, sesuai standar SQL-92 (halaman 191, Kasus 3a) bit SELECT dari EXISTS diabaikan.

gbn
sumber