微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

oracle – 为什么这个查询有效?

我有两个表,table_a(id,name)和table_b(id),让我们说在Oracle 12c上.

为什么此查询不返回异常?

select * from table_a where name in (select name from table_b);

据我所知,Oracle认为这是

select * from table_a where name = name;

但我没有得到的是为什么?

即使table_b没有名称列,查询在语法上也是正确的sql.原因是范围解决.

解析查询时,首先检查table_b是否具有名称列.因为它没有,所以检查table_a.仅当两个表都没有名称列时才会抛出错误.

最后,查询执行如下:

select a.* 
from table_a  a
where a.name in (select a.name 
                 from table_b  b
                );

至于查询将为table_a的每一行提供的结果,子查询(从table_b中选择名称) – 或(从table_b b中选择a.name) – 是一个具有相同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 docs: Resolution of Names in Static SQL Statements中的内部捕获中的类似示例B-6以及“在SELECT和DML语句中避免内部捕获”中的建议段落:

Qualify each column reference in the statement with the appropriate table alias.

原文地址:https://www.jb51.cc/oracle/205334.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐