Oracle SQL Query在12C但不在11g中工作

时间:2017-10-31 10:36:14

标签: sql oracle oracle11g oracle12c

我的Oracle SQL查询在12C中运行良好,但在11g中运行不正常。我在下面给出了一个类似的例子。请解释这是否是在12C中修复的错误/增强。

CREATE TABLE MSI_OWNER.VINOTH_TEST1
(
  COL1  VARCHAR2(100 BYTE),
  SAL   NUMBER,
  YEAR  NUMBER
)

Insert into MSI_OWNER.VINOTH_TEST1   (COL1, SAL, YEAR) Values   ('Vinoth', 100, 1);
Insert into MSI_OWNER.VINOTH_TEST1   (COL1, SAL, YEAR) Values   ('Vinoth', 100, 2);
COMMIT;

  SELECT col1,
         (SELECT MAX (its)
            FROM (SELECT MAX (year) its
                    FROM vinoth_test1 x
                   WHERE x.col1 = a.col1))
            max_year,
         sal
    FROM vinoth_test1 a
GROUP BY col1, sal

请注意,我已经写了一个不同的逻辑来解决这个问题,但我想知道这是11g中的错误还是12C中的增强。

Error in 11g: ORA-00904: "A"."COL1": invalid identifier

2 个答案:

答案 0 :(得分:3)

在任一数据库中,您都可以将其写为:

select col1, sal,
       max(max(year)) over (partition by col1)
from vinoth_test1
group by col1, sal;

不需要子查询。如前所述,您不需要附加级别的子查询。最里面的子查询只返回一行无论如何

Oracle只允许对子查询中的直接父级进行相关引用 - 而不是更高级别的父级。这似乎认为您的查询不适用于任何版本的Oracle。但是,我相信Oracle 12c会在强加此规则之前对进行一些优化。 documentation暗示了这一点:

  

Oracle在嵌套子查询时执行相关子查询   引用一个引用父语句的表中的列   子查询之上的级别。 。 。 。一个   相关子查询在概念上针对每一行进行一次评估   由父语句处理。但是,优化器可能会选择   将查询重写为连接或使用其他一些技术   制定一个语义上等同的查询。 Oracle解决了   子查询中的非限定列,通过查看名为的表来查找   子查询,然后在父语句中命名的表中。

我怀疑这个优化是删除你不必要的子查询,因此允许查询编译。

答案 1 :(得分:2)

Oracle文档始终明确表示只允许一个级别的关联(尽管没有明确的原因,并且它违反了SQL标准)。

正如其中一位大师Solomon Yakobson在OTN中已经多次解释过,在每个新版本中,在子版本1中(如在10.1,11.1中),更深层次的关联工作正常,就像OP一样注意到。它曾经在子版本2(10.2,11.2)中被“修复”(灵活性被收回)。 12.1具有相同的“增强”(所有级别的相关性),12.2没有把它拿走 - 尽管文档STILL表示相关性不允许超过一个级别。特别是因为当我们使用WITH子句编写查询时不存在这样的限制,所以Oracle没有理由继续使用该限制。

https://docs.oracle.com/database/122/SQLRF/Using-Subqueries.htm#SQLRF52357

当嵌套子查询引用一个表中的一个列时,Oracle会执行一个相关子查询,该表引用子查询上方的父语句一个级别