sql – 使用破坏的子选择查询应该导致错误但返回行

我不明白这种情况下的行为.根据我的理解,使用无效子查询查询应该会导致错误.但在此示例中,它返回一些行.

测试数据:

create table test_values ( tst_id number,tst_id2 number,tst_value varchar2( 10 ) );

create table test_lookup ( tst_id number,tst_value varchar2( 10 ) );

insert into test_values( tst_id,tst_id2,tst_value ) values ( 1,2,'a' );
insert into test_values( tst_id,'b' );
insert into test_values( tst_id,tst_value ) values ( 2,'c' );
insert into test_values( tst_id,'d' );

insert into test_lookup( tst_id,'findMe' );

commit;

按预期工作:

select * from test_values where tst_id in ( select tst_id from test_lookup where tst_value = 'findMe' );

/*
    TST_ID    TST_ID2 TST_VALUE 
---------- ---------- ----------
         1          2 b         
         1          2 a   
*/

select tst_id2 from test_lookup where tst_value = 'findMe'; 
--ORA-00904: "TST_ID2": invalid identifier

但是下面的查询也是检索行,显然是从“test_values”-table中获取“test_id2” – 列,而不是从子查询中所述的“test_lookup”-table中获取,尽管不使用内部和外部的别名部分.

select * from test_values where tst_id in ( select tst_id2 from test_lookup where tst_value = 'findMe' );

/*
   TST_ID    TST_ID2 TST_VALUE  
---------- ---------- ----------
         2          2 c         
         2          2 d         
*/

解决方法

原因是,当子查询中不存在unaliased列但外部查询中确实存在时,Oracle假定您引用外部查询中的列.

使用别名,您感到困惑的查询将如下所示:

select *
from   test_values tv
where  tv.tst_id in (select tv.tst_id2
                     from   test_lookup tl
                     where  tl.tst_value = 'findMe');

希望这会让事情变得更清楚?

您所看到的问题是一个非常好的示例,说明为什么您应该始终使用它们来自哪个表来标记列 – 这样可以更容易地维护查询以便开始!

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...