【问题标题】:(Oracle)Correlated subquery usage(Oracle)相关子查询使用
【发布时间】:2020-11-15 06:43:22
【问题描述】:

下面的子查询 query1 工作正常。 但是,当我将 equi 条件放入 -sort of-nested 子句(如 query2)中时,它会显示错误 ORA-00904。 这是关联子查询的错误使用还是其他原因?

--Query1: It shows expected result.

    SELECT
    O.ENAME
    O,SAL
    ,(SELECT COUNT(*)
        FROM SCOTT.EMP I
        WHERE I.SAL>O.SAL  --correlated to outer
     ) AS RESULT
    from SCOTT.EMP O;


--Query2:ORA-00904: "O"."SAL": invalid identifier shows. How to modify to use correlated subquery?

    SELECT
    O.ENAME
    O,SAL
    ,(
    WITH TEMP AS 
        (
        SELECT COUNT(*)
        FROM SCOTT.EMP I
        WHERE I.SAL>O.SAL   --I have put equi condistion here 
        )
    SELECT * FROM TEMP
    )  AS RESULT
    from SCOTT.EMP O;

【问题讨论】:

  • 您使用的是哪个版本的 Oracle?在 12.1(我认为)之前,父/子引用有一个级别的限制;但不确定在以后的版本中如何与 CTE 一起使用。

标签: oracle subquery window-functions correlated-subquery ora-00904


【解决方案1】:

我认为第二个选项是对相关子查询的错误使用,不是因为比较,而是因为使用了 with 子句。 我想记住,您应该尽可能避免相关子查询

WITH 子句或子查询因式分解子句可以作为内联视图处理或解析为临时表。后者的优点是重复引用子查询可能效率更高,因为数据很容易从临时表中检索出来,而不是每次引用都重新查询。

在第二个查询的第三列中,您希望从内联视图中获取结果。问题是内联视图的解析是独立完成的,因此不能引用外部查询中的任何内容。

SQL> create table emp ( ename varchar2(10) , sal number ) ;

Table created.

SQL> insert into emp values ( 'AAA' , 1000 ) ;

insert into emp values ( 'BBB' , 1000 ) ;

insert into emp values ( 'CCC' , 1000 ) ;

insert into emp values ( 'DDD' , 1000 ) ;
1 row created.

SQL> SQL>
1 row created.

SQL> SQL>
1 row created.

SQL> SQL>

1 row created.

SQL> select * from emp ;

ENAME             SAL
---------- ----------
AAA              1000
BBB              1000
CCC              1000
DDD              1000

要使用内联视图编写查询,必须在外部查询中完成过滤

SELECT
    O.ENAME
    O,SAL
    ,(
    WITH TEMP AS 
        (
        SELECT * FROM EMP 
        )
    SELECT count(*) FROM TEMP t WHERE t.SAL>O.SAL
    )  AS RESULT
    from EMP O;
O                 SAL     RESULT
---------- ---------- ----------
AAA              1000          0
BBB              1000          0
CCC              1000          0
DDD              1000          0

【讨论】:

    【解决方案2】:

    已经说明第二个查询没有正确使用with

    不过,我建议您的查询可以更简单、更有效地表达。对于每个员工,您要计算有多少员工的薪水更高。窗口函数是这里的方法:

    select e.*, rank() over(order by salary desc) - 1 result
    from scott.emp e
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多