В личном проекте глаз споткнулся о запрос, который выполнился, а не упал с ошибкой из-за отсутствующего поля. Вот запрос, который иллюстрирует подобное поведение СУБД (синтаксис MySQL 8):
with table_a(name, surname) as (
select 'Вася' as name, 'Васильев' as surname
union select all 'Петя', 'Петров'
union select all 'Иван', 'Иванов'
),
table_b(surname, age) as (
select 'Васильев' as surname, 45 as age
union select all 'Петров', 40
union select all 'Иванов', 35
)
select
*
from
table_a
where
(name, surname) in (select name, surname from table_b);
— хотя в CTE-представлении table_b нет поля name, MySQL вернёт все три записи из table_a. И происходит это потому, что не найдя поле name в подзапросе, MySQL начинает поиск снаружи подзапроса и находит поле в основной таблице запроса. Запрос выше эквивалентен следующему:
select
*
from
table_a as ta
where
(ta.name, ta.surname) in (
select ta.name, tb.surname from table_b as tb
);
Избежать подобной неоднозначности и случайных корреляций поможет явное указание алиасов таблиц в запросах. Даже в простых запросах.