A consulta está sintaticamente correta no SQL, mesmo table_b
que não tenha uma name
coluna. O motivo é a resolução do escopo.
Quando a consulta é analisada, primeiro é verificado se table_b
há uma name
coluna. Como isso não acontece, então table_a
é verificado. Isso geraria um erro apenas se nenhuma das tabelas tivesse uma name
coluna.
Finalmente, a consulta é executada como:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
Quanto aos resultados que a consulta forneceria, para cada linha da table_a
subconsulta (select name from table_b)
- ou (select a.name from table_b b)
- é uma tabela com uma única coluna com o mesmo a.name
valor e o mesmo número de linhas table_b
. Portanto, se table_b
tiver 1 ou mais linhas, a consulta será executada como:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
ou:
select a.*
from table_a a
where a.name = a.name ;
ou:
select a.*
from table_a a
where a.name is not null ;
Se table_b
estiver vazio, a consulta não retornará linhas (thnx para @ughai para apontar essa possibilidade).
Esse (o fato de você não receber um erro) é provavelmente o melhor motivo para que todas as referências de coluna sejam prefixadas com o nome / alias da tabela. Se a consulta foi:
select a.* from table_a where a.name in (select b.name from table_b);
você teria o erro imediatamente. Quando os prefixos de tabela são omitidos, não é difícil que esses erros ocorram, especialmente em consultas mais complexas e, ainda mais importante, passam despercebidas.
Leia também nos documentos da Oracle: Resolução de nomes em instruções SQL estáticas o exemplo semelhante B-6 em Captura interna e as recomendações nos parágrafos Evitar captura interna em instruções SELECT e DML :
Qualifique cada referência de coluna na instrução com o alias da tabela apropriado.
Porque
Isso significa que, para determinar se a subconsulta está correlacionada, o Oracle deve tentar resolver os nomes na subconsulta, incluindo também o contexto da instrução externa. E para
name
não fixado é a única resolução possível.fonte
Como não há
name
campo,table_b
o Oracle escolhe o campotable_a
. Eu tentei oEXPLAIN PLAN
mas isso me deu apenas que existe umTABLE ACCESS
FULL
. Presumo que isso gere algum tipo de produto cartesiano entre as duas tabelas que resultam em uma lista de todos os nomestable_a
retornados pela subconsulta.fonte
from table_a where ...
. Ele retornará todas as linhas,table_a
exceto aquelas quename
são nulas.TABLE ACCESS FULL
é apenas uma maneira da Oracle dizer que está fazendo uma varredura seqüencial.