¿Cómo reemplazo esta cláusula where con una unión?


8

Típicamente cuando veo SQL que usa algo como:

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

Reemplazo el wherecon esto:

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

¿Es posible hacer lo mismo con el inverso en caso de que sea un not in(como a continuación) en lugar de una 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
                        )  

Consideraciones adicionales

Puedo hacer esto:

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

Respuestas:


6

Si. Se puede reemplazar con una IZQUIERDA UNIRSE ... DONDE la tecla ES NULA. Realiza mucho más 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

¿Cuál es el rendimiento diferente entre los dos? Creo que las uniones son mucho más rápidas que usar en (...) o no en (...), nunca pensé que existe (...) ¿alguna idea?
kacalapy

también puedo incluir cada cosa en la unión, ver mi edición al final de la pregunta
kacalapy

1
Debes tener la cláusula WHERE como dije.
Eric Humphrey - lotsahelp

44
"Se realiza mucho más rápido"? Que NO EXISTE o NO EN? Si no está adentro, sí. Si NO EXISTE, bastante igual.
gbn

1
Ejemplo o en SO
gbn

7

Su NO EXISTE es más eficiente en la mayoría de los casos.

IZQUIERDA UNIR internamente coincide con todas las filas y luego filtra a IS NULL. NO EXISTE no lo hace. Esta multiplicación de filas también ocurre en todos los códigos basados ​​en JOIN, por lo que puede necesitar un agregado adicional (DISTINCT) para corregir la salida

NOT IN generalmente es incorrecto porque los NULL no causan coincidencia.

También puede usar EXCEPTO que proporciona el mismo plan que NO EXISTE.

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 su información, según el estándar SQL-92 (página 191, caso 3a), se ignora el bit SELECT de EXISTS.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.