Come posso sostituire questa clausola where con un join?


8

In genere quando vedo SQL che utilizza qualcosa di simile:

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

Sostituisco il wherecon questo:

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

È possibile fare lo stesso con l'inverso nel caso in cui sia una not in(come sotto) invece di una inclausola?

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
                        )  

Ulteriori considerazioni

Posso farlo:

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

Risposte:


6

Sì. È possibile sostituire con un JOIN SINISTRA ... DOVE LA chiave È NULL. Si esibisce molto più velocemente.

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

qual è la prestazione diversa tra i due? Penserei che i join siano molto più veloci dell'uso in (...) o non in (...), non hai mai pensato di esistere (...) qualche idea?
kacalapy,

posso anche includere ogni cosa nel join, vedere la mia modifica in fondo alla domanda
kacalapy,

1
Devi avere la clausola WHERE come ho affermato.
Eric Humphrey - lotsahelp,

4
"Esegue molto più velocemente"? Che NON ESISTE o NON IN? Se NON IN, sì. Se NON ESISTE, abbastanza uguale.
gbn

1
Esempio o su SO
gbn

7

Il tuo NOT EXISTS è più efficiente nella maggior parte dei casi.

LEFT JOIN abbina internamente tutte le righe, quindi filtra su IS NULL. NON ESISTE no. Questa moltiplicazione di riga si verifica anche in tutto il codice basato su JOIN, pertanto potrebbe essere necessario un aggregato aggiuntivo (DISTINCT) per correggere l'output

NOT IN è generalmente sbagliato perché i NULL non causano alcuna corrispondenza.

Puoi anche usare EXCEPT che fornisce lo stesso piano di 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          

Cordiali saluti, secondo lo standard SQL-92 (pagina 191, Caso 3a) il bit SELECT dell'EXISTS viene ignorato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.