Como substituo esta cláusula where por uma junção?


8

Normalmente, quando vejo o SQL que usa algo como:

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

Eu substituo o wherepor este:

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

É possível fazer o mesmo com o inverso, caso seja uma not in(como abaixo) em vez de uma incláusula?

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
                        )  

Considerações adicionais

Posso fazer isso:

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

Respostas:


6

Sim. Você pode substituir por uma tecla LEFT JOIN ... WHERE IS NULL. Executa muito mais rápido.

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 o desempenho diferente entre os dois? Eu acho que as junções são muito mais rápidas do que usar em (...) ou não em (...), nunca pensei em existir (...) alguma idéia?
— 22411 kacalapy

Também posso incluir tudo na junção, ver a minha edição na parte inferior da questão
— kacalapy

11
Você precisa ter a cláusula WHERE como afirmei.
— Eric Humphrey - lotsahelp

4
"Executa muito mais rápido"? Do que NÃO EXISTE ou NÃO ESTÁ? Se NÃO estiver, sim. Se NÃO EXISTE, é praticamente igual.
— gbn 14/02


7

Seu NOT EXISTS é mais eficiente na maioria dos casos.

LEFT JOIN combina internamente todas as linhas e depois filtra para IS NULL. NÃO EXISTE não. Essa multiplicação de linhas também acontece em todo o código baseado em JOIN, portanto, você pode precisar de um agregado extra (DISTINCT) para corrigir a saída

NOT IN geralmente está errado porque NULLs não causam nenhuma correspondência.

Você também pode usar EXCEPT, que fornece o mesmo plano que 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          

Para sua informação, de acordo com o padrão SQL-92 (página 191, Caso 3a), o bit SELECT dos EXISTS é ignorado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.