Existe una alternativa, un tanto rebuscada, pero que reduce considerablemente el tiempo necesario de la consulta. Vamos a intentar explicarla mediante un ejemplo; buscamos en dos tablas, A y B, los registros de A que NO estén en B (tomando como base un campo determinado).
Normalmente haríamos:
/* Esto es usando NOT IN en un subquery */
select *
from A
where A.campo not in (select B.campo from B);
/* La alternativa sería: */
select A.*
from A,B
where A.campo = B.campo(+)
and B.campo is null;
Aquí estamos realizando una outer join (donde aparece el signo “+”), es decir, seleccionamos tanto los registros de A que se correspondan con uno de B, como los registros de A que NO se correspondan.
Luego seleccionamos los registros en los que el campo de B sea nulo (no confundirse, recordad que por la outer join estamos seleccionando registros de A), que son precisamente los de A de la outer join que no se corresponden con ninguno de B.
El resultado es equivalente a los registros de A que NO están en B.
Adicionalmente, podemos seleccionar los registros de A que NO cumplen cierta condición (condición que se encuentra en la tabla B y por tanto allí deberemos comprobarla). De nuevo estamos en el caso del posible retardo al tratar de comprobar una condición negativa, y la solución es análoga; basta con añadir la condición a comprobar, pero, ojo, de forma positiva:
Aquí estamos realizando una outer join (donde aparece el signo “+”), es decir, seleccionamos tanto los registros de A que se correspondan con uno de B, como los registros de A que NO se correspondan.
Luego seleccionamos los registros en los que el campo de B sea nulo (no confundirse, recordad que por la outer join estamos seleccionando registros de A), que son precisamente los de A de la outer join que no se corresponden con ninguno de B.
El resultado es equivalente a los registros de A que NO están en B.
Adicionalmente, podemos seleccionar los registros de A que NO cumplen cierta condición (condición que se encuentra en la tabla B y por tanto allí deberemos comprobarla). De nuevo estamos en el caso del posible retardo al tratar de comprobar una condición negativa, y la solución es análoga; basta con añadir la condición a comprobar, pero, ojo, de forma positiva:
Select A.*
from A,B
where A.id = B.idA(+)
and B.idA is null
and B.campo_cond(+) = valor;
Es decir, aunque la condición comprueba que sea igual a cierto valor, el resultado final será, paradójicamente, los registros de A que NO cumplen esa condición (inclusive aquellos que no tienen correspondencia con ninguno de B). En este caso el campo de conexión sería la clave de A.
Una advertencia: para que esto funcione correctamente, es importante asegurarse de que efectivamente existen registros de A que se correspondan con otros de B y que CUMPLAN la condición, ya que si no los resultados serían incorrectos; recuerda que la consulta se basa en la negación de una condición inicial, si ésta no existe, este método no es válido.
Fuente aquí
Fuente aquí
No hay comentarios:
Publicar un comentario