Это не ясное заявление, но the documentation does refer to this behaviour:
Если столбцы в подзапросе имеют такое же имя, как и столбцы в содержащем заявлении, то вы должны префикс любой ссылки на столбец таблицы из содержащий оператор с именем таблицы или псевдонимом. Чтобы упростить чтение, всегда квалифицируйте столбцы в подзапросе с именем или псевдонимом таблицы, представления или материализованного представления.
Поэтому в основном это говорит о том, что для вашего первого заявления ссылки t1.a
вы должны явно использовать это имя (или псевдоним):
select * from t1 where id in (select id from t2 where t1.a = 'aa');
Если нет, то он будет использовать таблицу в подзапроса по умолчанию. Он не является двусмысленным для синтаксического анализатора, потому что сначала он будет рассматривать таблицы на одном уровне (под) запроса и только смотреть на внешний уровень, если он не может найти этот столбец на текущем уровне. Возможно, это не так, как вы ожидаете, и я согласен с жалобой на то, что было бы двусмысленно избегать тонких ошибок, которые дают неправильные результаты; но так оно и работает.
Но он также говорит, что безопаснее всегда явно в любом случае:
select * from t1 where t1.id in (select t2.id from t2 where t2.a = 'aa');
или
select * from t1 where t1.id in (select t2.id from t2 where t1.a = 'aa');
и для второго утверждения:
select * from t1 where t1.id in (select t3.id from t3 where t1.a = 'aa');
Да, это именно то, что мы имеем в наших соглашениях о кодировании. Но иногда конечные пользователи не придерживаются их ;-) Итак, мы попробовали верхний удалить некоторые устаревшие атрибуты, в то время как операторы продолжали выполнять, но полностью сделали не то, потому что это взяло другой атрибут. Итак, мы, где интересно, не должно быть ошибки в первую очередь? –
@Whisky_jb - Я согласен, что ошибка имеет смысл здесь, но это не то, что Oracle решил делать по любой причине. Такое поведение, вероятно, восходит к самым ранним дням, и я не знаю, как это изменить. –
@AlexPoole: это поведение соответствует стандарту SQL. Oracle следовал стандарту здесь. –