我不了解这种情况下的行为。据我了解,带有无效子查询的查询应导致错误。但在此示例中,它返回一些行。
测试数据:
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 */
原因是因为当子查询中不存在非别名列,但外部查询中确实存在非别名列时,Oracle会假定您正在从外部查询中引用该列。
使用别名,您感到困惑的查询看起来像:
select * from test_values tv where tv.tst_id in (select tv.tst_id2 from test_lookup tl where tl.tst_value = 'findMe');
希望这可以使事情变得更清楚?
您所看到的问题是一个很好的示例,说明了为什么始终应使用列来自哪个表来标记您的列-这样可以更轻松地维护查询的开始!