SQL别名作用域疑问:外部pn别名未被子查询识别致结果异常
SQL别名作用域的核心规则解释
别名的就近覆盖原则
SQL解析器处理别名时会优先使用当前作用域内的定义。如果子查询里定义了和外部查询同名的别名(比如pn),外部的同名别名会被直接屏蔽,子查询只会调用自己内部的那个。不同子查询类型的别名可见性
- 相关子查询:如果子查询写在SELECT、WHERE、HAVING这类子句里,且依赖外部查询的行数据,那外部的表别名是可见的。比如:
这里子查询里的SELECT u.name FROM user u WHERE EXISTS (SELECT 1 FROM order o WHERE o.user_id = u.id);u就是外部查询定义的别名,能正常关联数据。 - 非相关子查询(派生表):如果子查询是放在FROM子句里的派生表,它会独立于外部查询执行,外部的别名对它完全不可见。比如你第一个查询里,子查询在FROM子句中,引用外部的
pn相当于引用了一个不存在的对象,自然返回大量NULL;而当你在派生表内部重新定义pn别名时,它能正常读取自身关联的表数据,所以返回正确结果。
- 相关子查询:如果子查询写在SELECT、WHERE、HAVING这类子句里,且依赖外部查询的行数据,那外部的表别名是可见的。比如:
常见误区
不少人会误以为所有子查询都能访问外部别名,但实际上只有相关子查询可以。如果子查询是用来生成临时表的派生表,它和外部查询是完全独立的执行顺序,根本拿不到外部的行数据,自然识别不了外部别名。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

