La query è SQL sintatticamente corretto anche se table_b
non ha una name
colonna. Il motivo è la risoluzione dell'ambito.
Quando la query viene analizzata, viene prima verificato se table_b
ha una name
colonna. Dal momento che non lo fa, quindi table_a
viene controllato. Avrebbe generato un errore solo se nessuna delle tabelle avesse una name
colonna.
Infine la query viene eseguita come:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
Per quanto riguarda i risultati che la query darebbe, per ogni riga di table_a
, la sottoquery (select name from table_b)
- o (select a.name from table_b b)
- è una tabella con una singola colonna con lo stesso a.name
valore e tante righe quante table_b
. Quindi, se table_b
ha 1 o più righe, la query viene eseguita come:
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 ;
Se table_b
è vuoto, la query non restituirà alcuna riga (grazie a @ughai per indicare quella possibilità).
Questo (il fatto che non si ottiene un errore) è probabilmente il motivo migliore per cui tutti i riferimenti di colonna devono essere preceduti dal nome / alias della tabella. Se la query era:
select a.* from table_a where a.name in (select b.name from table_b);
avresti subito subito l'errore. Quando si omettono i prefissi delle tabelle, non è difficile che si verifichino tali errori, soprattutto nelle query più complesse, e ancora più importanti, inosservate.
Leggi anche nei documenti Oracle: Risoluzione dei nomi nelle istruzioni SQL statiche l'esempio simile B-6 in Acquisizione interna e le raccomandazioni nei paragrafi Evitare l'acquisizione interna in Dichiarazioni SELECT e DML :
Qualificare ogni riferimento di colonna nell'istruzione con l'alias di tabella appropriato.