Posteado por: alfayate | agosto 25, 2010

Trucos Oracle: Alternativa a NOT IN

Problema: Necesitamos seleccionar un determinado valor (o varios) que NO pertenezca a un conjunto dado. Para esto, claro está, existe el operador de comparación NOT IN, que también puede usarse en subconsultas. Normalmente funciona muy bien, pero (especialmente en el caso de las subconsultas) puede resultar muuuy lento; dado que para saber si un elemento NO está en un conjunto, no queda más remedio que compararlo con TODOS los elementos del conjunto. Si el conjunto es muy grande y además queremos comprobar muchos elementos (caso muy típico en las subconsultas, p.e. buscar los elementos de una tabla que no están en otra) entonces la consulta puede ralentizarse enormemente.

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:

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:

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; recordad 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.

Anuncios

Responses

  1. […] Actualizados : Trucos Oracle: Alternativa a NOT IN Trucos Oracle: Comparación de cadenas similares por proximidad Trucos Oracle: Comprobar si un […]


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: