La consulta es SQL sintácticamente correcto incluso si table_b
no tiene una name
columna. La razón es la resolución del alcance.
Cuando se analiza la consulta, primero se verifica si table_b
tiene una name
columna. Como no lo hace, entonces table_a
se verifica. Lanzaría un error solo si ninguna de las tablas tuviera una name
columna.
Finalmente la consulta se ejecuta como:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
En cuanto a los resultados que daría la consulta, por cada fila de table_a
la subconsulta (select name from table_b)
, o bien (select a.name from table_b b)
, es una tabla con una sola columna con el mismo a.name
valor y tantas filas como table_b
. Entonces, si table_b
tiene 1 o más filas, la consulta se ejecuta como:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
o:
select a.*
from table_a a
where a.name = a.name ;
o:
select a.*
from table_a a
where a.name is not null ;
Si table_b
está vacío, la consulta no devolverá filas (gracias a @ughai por señalar esa posibilidad).
Eso (el hecho de que no obtiene un error) es probablemente la mejor razón por la que todas las referencias de columna deben tener como prefijo el nombre / alias de la tabla. Si la consulta fue:
select a.* from table_a where a.name in (select b.name from table_b);
Habría recibido el error de inmediato. Cuando se omiten los prefijos de tabla, no es difícil que ocurran tales errores, especialmente en consultas más complejas, y aún más importante, pasan desapercibidas.
Lea también en documentos de Oracle: Resolución de nombres en declaraciones estáticas de SQL, el ejemplo similar B-6 en Captura interna y las recomendaciones en los párrafos Evitar captura interna en las declaraciones SELECT y DML :
Califique cada referencia de columna en la declaración con el alias de tabla apropiado.
Porque
Significa que para determinar si la subconsulta está correlacionada, Oracle debe intentar resolver los nombres en la subconsulta, incluido el contexto de la declaración externa también. Y para
name
no prefijado es la única resolución posible.fuente
No hay
name
campo en,table_b
así que Oracle toma el detable_a
. Probé elEXPLAIN PLAN
pero esto me dio solo que hay unTABLE ACCESS
FULL
. Supongo que esto generará algún tipo de producto cartesiano entre ambas tablas que dará como resultado que la subconsultatable_a
devuelva una lista de todos los nombres .fuente
from table_a where ...
. Devolverá todas las filas,table_a
excepto las quename
sean nulas.TABLE ACCESS FULL
es solo la forma en que Oracle le dice que está haciendo un escaneo secuencial.