查询适用于oracle 12c但不适用于11g

时间:2018-06-09 10:25:01

标签: oracle oracle11g oracle12c

我在sql(oracle)中有简单(但不那么聪明)的代码。 这个SQL在oracle版本12c上工作正常但在oracle v.11g上有例外。你可以给mi回答为什么?



    create table app_status (id_status int, description varchar2(20 char), range_char char(1));
    /
    create table app (id_app int,  description varchar2(20 char), range_char char(1));
    /
    insert into app_status (id_status, description,range_char) values (1,'opis 1','a');
    insert into app_status (id_status, description,range_char) values (2, 'opis 2','b');
    insert into app_status (id_status, description,range_char) values (3, 'opis 3','a');
    insert into app_status (id_status, description,range_char) values (4, 'opis 4','a');
    /
    insert into app (id_app,description,range_char) values (1,'app 1','a');
    insert into app (id_app,description,range_char) values (2,'app 2','a');
    insert into app (id_app,description,range_char) values (3,'app 3','a');
    insert into app (id_app,description,range_char) values (4,'app 4','b');
    insert into app (id_app,description,range_char) values (5,'app 5','a');
    insert into app (id_app,description,range_char) values (6,'app 6','a');
    insert into app (id_app,description,range_char) values (7,'app 7','c');
    insert into app (id_app,description,range_char) values (8,'app 8','a');
    insert into app (id_app,description,range_char) values (9,'app 9','a');
    /


    -- this query does not work on oracle v.11g
    select * from app where not exists (
           select id_status from (
                  select id_STATUS FROM APP_STATUS 
                  WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
                  ORDER BY ID_STATUS DESC 
           ) WHERE ROWNUM=1);

我在oracle 11g的规范中找不到信息,为什么它不起作用。也许它在12c上不正确,但更高版本容忍不规则?

2 个答案:

答案 0 :(得分:1)

只需注释掉一个子查询并删除ORDER BY:

 select * from app where not exists (
  --         select id_status from (
                  select id_STATUS FROM APP_STATUS 
                  WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
  --                ORDER BY ID_STATUS DESC 
 --          ) WHERE ROWNUM=1
 );

或只是删除它们:

     select * from app where not exists (
                      select id_STATUS FROM APP_STATUS 
                      WHERE APP_STATUS.RANGE_CHAR = APP.RANGE_CHAR 
     );

此子查询在NOT EXISTS运算符中是不必要的,此运算符检查是否存在任何行,不需要仅过滤掉1条记录,也不需要订购重新设置。

顺便说一句,如果你删除这个子查询和ORDER BY,那么整个查询可能会更快,同时给出完全相同的结果。

答案 1 :(得分:1)

欢迎来到SO!

我可以在11g上重现你的异常:

SELECT * 
  FROM app
 WHERE NOT EXISTS ( 
                   SELECT id_status 
                     FROM (
                           SELECT id_status 
                             FROM app_status 
                            WHERE app_status.range_char = app.range_char 
                            ORDER BY id_status DESC
                           ) 
                     WHERE ROWNUM=1
                   );
Version 11.2.0.2 ORA-00904: "APP"."RANGE_CHAR": invalid identifier
Version 12.2.0.1 OK

我同意@krokodilko,查询可以而且应该简化,例如

SELECT * 
  FROM app 
 WHERE NOT EXISTS ( 
                   SELECT * 
                     FROM app_status 
                    WHERE app_status.range_char = app.range_char 
                   );

然后在11.2和12.2中运行,我仍然感到困惑,为什么这被认为是11.2中的错误。

有人知道细节吗?