Запрос является синтаксически правильным SQL, даже если table_b
не имеет name
столбца. Причина в разрешении области.
Когда запрос анализируется, сначала проверяется table_b
наличие name
столбца. Так как это не так, то table_a
проверяется. Это выдаст ошибку, только если ни в одной из таблиц не будет name
столбца.
Наконец запрос выполняется как:
select a.*
from table_a a
where a.name in (select a.name
from table_b b
);
Что касается результатов, то запрос даст для каждой строки table_a
подзапроса (select name from table_b)
- или (select a.name from table_b b)
- таблицу с одним столбцом с тем же a.name
значением и таким же количеством строк, как table_b
. Итак, если table_b
есть 1 или более строк, запрос выполняется так:
select a.*
from table_a a
where a.name in (a.name, a.name, ..., a.name) ;
или:
select a.*
from table_a a
where a.name = a.name ;
или:
select a.*
from table_a a
where a.name is not null ;
Если table_b
пусто, запрос не будет возвращать строк (thnx в @ughai за указание этой возможности).
Это (тот факт, что вы не получаете сообщение об ошибке), вероятно, является лучшей причиной того, что все ссылки на столбцы должны начинаться с имени таблицы / псевдонима. Если запрос был:
select a.* from table_a where a.name in (select b.name from table_b);
Вы бы сразу получили ошибку. Когда префиксы таблиц опущены, такие ошибки не возникают, особенно в более сложных запросах, и, что еще важнее, остаются незамеченными.
Читайте также в документации Oracle: Разрешение имен в статических операторах SQL, аналогичный пример B-6 во Внутреннем захвате и рекомендации во избежании внутреннего захвата в параграфах SELECT и DML Statements :
Укажите для каждой ссылки на столбец в операторе соответствующий псевдоним таблицы.
Потому что
Это означает, что для определения того, является ли подзапрос коррелированным, Oracle должен попытаться разрешить имена в подзапросе, включая внешний контекст оператора. А для без префиксов
name
это единственное возможное разрешение.источник
name
Поле отсутствует,table_b
поэтому Oracle его беретtable_a
. Я попробовал,EXPLAIN PLAN
но это дало мне только то, что естьTABLE ACCESS
FULL
. Я предполагаю, что это сгенерирует некоторый вид декартового произведения между обеими таблицами, в результате чегоtable_a
подзапрос возвращает список всех имен .источник
from table_a where ...
. Он вернет все строки,table_a
кроме тех, которыеname
являются нулевыми.TABLE ACCESS FULL
это просто способ Oracle сказать вам, что он выполняет последовательное сканирование.