La requête est syntaxiquement correcte, même si SQL table_b
n'a pas de name
colonne. La raison est la résolution de la portée.
Lorsque la requête est analysée, il est d'abord vérifié s'il table_b
contient une name
colonne. Puisqu'il ne le fait pas, alors table_a
est vérifié. Une erreur ne serait générée que si aucune des tables n'avait de name
colonne.
Enfin, la requête est exécutée comme suit:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
En ce qui concerne les résultats, la requête donnerait, pour chaque ligne de table_a
la sous (select name from table_b)
- requête - ou (select a.name from table_b b)
- est une table avec une seule colonne avec la même a.name
valeur et autant de lignes que table_b
. Donc, si table_b
a 1 ou plusieurs lignes, la requête s'exécute en tant que:
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 ;
Si table_b
est vide, la requête ne renverra aucune ligne (thnx à @ughai pour indiquer cette possibilité).
Cela (le fait que vous n'ayez pas d'erreur) est probablement la meilleure raison pour que toutes les références de colonne soient préfixées du nom / alias de la table. Si la requête était:
select a.* from table_a where a.name in (select b.name from table_b);
vous auriez eu l'erreur tout de suite. Lorsque les préfixes de table sont omis, il n'est pas difficile que de telles erreurs se produisent, en particulier dans les requêtes plus complexes, et plus important encore, passent inaperçues.
Lisez également dans Oracle docs: Résolution de noms dans des instructions SQL statiques, exemple B-6 similaire en capture interne et recommandations dans les paragraphes Eviter la capture interne dans les instructions SELECT et DML :
Qualifiez chaque référence de colonne dans l'instruction avec l'alias de table approprié.
Car
Cela signifie que pour déterminer si la sous-requête est corrélée, Oracle doit également tenter de résoudre les noms dans la sous-requête, y compris le contexte de l'instruction externe. Et pour unprefixed
name
c'est la seule résolution possible.la source
Il n'y a pas de
name
champ dans la base de donnéestable_b
Oracletable_a
. J'ai essayé leEXPLAIN PLAN
mais cela m'a donné seulement qu'il y a unTABLE ACCESS
FULL
. Je suppose que cela générera une sorte de produit cartésien entre les deux tables, ce qui donnera une liste de tous les noms quitable_a
sont renvoyés par la sous-requête.la source
from table_a where ...
. Il renverra toutes les lignestable_a
sauf celles quiname
sont nulles.TABLE ACCESS FULL
C’est juste la façon dont Oracle vous dit qu’elle effectue une analyse séquentielle.