我在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上不正确,但更高版本容忍不规则?
答案 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中的错误。
有人知道细节吗?