Die Abfrage ist syntaktisch korrektes SQL, auch wenn table_b
keine name
Spalte vorhanden ist. Der Grund ist die Auflösung des Bereichs.
Beim Analysieren der Abfrage wird zunächst geprüft, ob table_b
eine name
Spalte vorhanden ist. Da dies nicht der Fall ist, table_a
wird geprüft. Es würde nur dann einen Fehler auslösen, wenn keine der Tabellen eine name
Spalte hätte.
Schließlich wird die Abfrage ausgeführt als:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
Was die Ergebnisse table_a
angeht, so ist die Abfrage für jede Zeile der Unterabfrage (select name from table_b)
- oder (select a.name from table_b b)
- eine Tabelle mit einer einzelnen Spalte mit demselben a.name
Wert und so vielen Zeilen wie möglich table_b
. Wenn also table_b
eine oder mehrere Zeilen vorhanden sind, wird die Abfrage wie folgt ausgeführt:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
oder:
select a.*
from table_a a
where a.name = a.name ;
oder:
select a.*
from table_a a
where a.name is not null ;
Wenn table_b
leer, gibt die Abfrage keine Zeilen zurück (danke an @ughai, um auf diese Möglichkeit hinzuweisen).
Das (die Tatsache, dass Sie keinen Fehler erhalten) ist wahrscheinlich der beste Grund, dass allen Spaltenreferenzen der Tabellenname / Alias vorangestellt werden sollte. Wenn die Abfrage lautete:
select a.* from table_a where a.name in (select b.name from table_b);
Sie hätten den Fehler sofort bekommen. Wenn Tabellenpräfixe weggelassen werden, ist es nicht schwierig, dass solche Fehler auftreten, insbesondere bei komplexeren Abfragen, und noch wichtiger, dass sie unbemerkt bleiben.
Lesen Sie auch in Oracle-Dokumenten: Auflösung von Namen in statischen SQL-Anweisungen das ähnliche Beispiel B-6 in Inner Capture und die Empfehlungen in den Absätzen Vermeiden von Inner Capture in SELECT- und DML-Anweisungen :
Qualifizieren Sie jede Spaltenreferenz in der Anweisung mit dem entsprechenden Tabellenalias.
weil
Dies bedeutet, dass Oracle versuchen muss , Namen in der Unterabfrage einschließlich des Kontexts der äußeren Anweisung aufzulösen , um festzustellen, ob die Unterabfrage korreliert ist . Und für Unfixed ist
name
es die einzig mögliche Auflösung.quelle
Es gibt kein
name
Feld in,table_b
also nimmt Oracle das vontable_a
. Ich habe das versuchtEXPLAIN PLAN
aber das gab mir nur das es eine gibtTABLE ACCESS
FULL
. Ich gehe davon aus, dass dies eine Art kartesisches Produkt zwischen beiden Tabellen erzeugt, das eine Liste aller Namentable_a
ergibt, in denen die Unterabfrage zurückgibt.quelle
from table_a where ...
. Es werden alle Zeilen mittable_a
Ausnahme derjenigen,name
die null sind, zurückgegeben.TABLE ACCESS FULL
Dies ist nur die Art und Weise, wie Oracle Ihnen mitteilt, dass ein sequentieller Scan durchgeführt wird.