select * from table where where子查询返回ORA-00904的子查询

时间:2017-12-14 08:45:49

标签: sql oracle11g ora-00904

查询:

SELECT COLUMN_NAME FROM MY_TABLE

返回

  

ORA-00904无效的标识符,因为MY_TABLE中没有COLUMN_NAME列,所以这么好。

查询:

SELECT * 
FROM OTHER_TABLE 
WHERE COLUMN_NAME IN (SELECT COLUMN_NAME FROM MY_TABLE)

它不仅不会失败,而且会返回完整的OTHER_TABLE。仅当内部查询选择“外部”表中的列时才会发生。

如果我运行相同的查询,只需将内部查询选择列更改为表中不存在但在外表中的表中不存在的不同列。

SELECT * 
FROM OTHER_TABLE 
WHERE COLUMN_NAME IN (SELECT DIFFERENT_NAME FROM MY_TABLE)
OTHER_TABLE

中不存在

DIFFERENT_NAME

ORA-00904无效标识符失败。

1.如何使用外部查询中存在但在内部查询中不存在的列的查询不会失败? 2.为什么它会返回完整的表格?

2 个答案:

答案 0 :(得分:0)

您可以使用"外部"中的列。 in子句中查询中的表。对于外部表中的每一行,从内部表中选择该行的column_name的值(类似于选择文字值时)。由于它与外部查询中的行的column_name值相同,因此它们显然相等,因此满足条件并返回行。

避免此类错误的良好防御措施是完全限定您要查询的列(最好使用表别名),因此查询会出错,而不是返回您不期望的内容:

SELECT *
FROM   other_table ot
WHERE  ot.column_name IN (SELECT mt.column_name -- causes error!
                          FROM   my_table mt) 

答案 1 :(得分:0)

想象一下,我们有两个表:TA包含字段ATB包含字段B,现在让我们写一些查询:

  select A   -- wrong: TB doesn't have A field
    from TB

但是这一个将确定并返回整个TB表,前提是B字段不为空且TA不为空:

  select *
    from TB 
   where B in (select B   -- <- B is from TB in both cases
                 from TA)

在这种情况下你有

  where B in (select B from TA)

等于

  -- 1. null in (...) is null, not true
  -- 2. we have not empty TA 
  where (B is not null) and Exists (select 1 from TA)

最后

  select *
    from TB 
   where B in (select C   -- wrong: there's no field C in TB as well as in TA
                 from TA)