小编典典

子选择损坏的查询应导致错误,但返回行

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, tst_id2, tst_value ) values ( 1, 2, 'b' );
insert into test_values( tst_id, tst_id2, tst_value ) values ( 2, 2,'c' );
insert into test_values( tst_id, tst_id2, tst_value ) values ( 2, 2,'d' );

insert into test_lookup( tst_id, tst_value ) values ( 1, '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”表中获取“ test_id2”列,而不是从子查询中所述的“
test_lookup”表中获取,尽管未在内部和外部使用别名部分。

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         
*/

阅读 190

收藏
2021-03-10

共1个答案

小编典典

原因是因为当子查询中不存在非别名列,但外部查询中确实存在非别名列时,Oracle会假定您正在从外部查询中引用该列。

使用别名,您感到困惑的查询看起来像:

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

希望这可以使事情变得更清楚?

您所看到的问题是一个很好的示例,说明了为什么始终应使用列来自哪个表来标记您的列-这样可以更轻松地维护查询的开始!

2021-03-10