Я пытаюсь обновить таблицу с помощью подзапроса, однако подзапрос содержит несколько объединений, поскольку я получаю данные из нескольких таблиц, и в качестве бизнес-требования я вынужден добавить порядок в подзапрос для сортировки элементы на основе первичного ключа, если порядок не добавлен, вывод будет неточным. Простой пример без соединений того, что я пытаюсь сделать:
UPDATE EMPLOYEES e
SET (e.JOB, e.SAL, e.COMM) =
(
SELECT p.JOB, p.SAL, p.COMM FROM EMP p WHERE p.ENAME = e.ENAME ORDER BY p.DEPTNO
)
WHERE DEPTNO = 30;
Основная проблема заключается в невозможности использовать Order by в подзапросе.
Это выдает сообщение об ошибке:
Error at line 4/80: ORA-00907: missing right parenthesis
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_220100", line 847
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1658
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_220100", line 833
ORA-06512: at "APEX_220100.WWV_FLOW_DYNAMIC_EXEC", line 1903
Если я удаляю Order by из подзапроса, я не получаю сообщения об ошибке, однако мой результат не является ожидаемым. Как я могу этого добиться?





Синтаксически недопустимо наличие предложения ORDER BY в самом внешнем подзапросе коррелированного подзапроса, поскольку порядок результатов не имеет значения, поскольку для подзапроса должна быть только одна соответствующая строка. Поэтому общий ответ на ваш вопрос заключается в том, что невозможно иметь предложение ORDER BY, потому что синтаксис запрещает это.
Начиная с Oracle 12 существует исключение, которое позволяет использовать предложение ORDER BY в коррелированном подзапросе, и это когда вы также используете FETCH FIRST ROW ONLY, чтобы гарантировать, что подзапрос возвращает только одну строку.
Итак, если вы получаете несколько строк для подзапроса и вам нужна только первая строка, то из Oracle 12 вы можете использовать:
UPDATE EMPLOYEES e
SET (e.JOB, e.SAL, e.COMM) = (SELECT p.JOB, p.SAL, p.COMM
FROM EMP p
WHERE p.ENAME = e.ENAME
ORDER BY p.DEPTNO
FETCH FIRST ROW ONLY)
WHERE DEPTNO = 30;
Однако кажется более вероятным, что вы захотите использовать что-то еще для корреляции запросов, чтобы получить только одну строку.
as a business requirement I am forced to add an Order by in the sub-query to sort elements based on the primary key
Похоже, это не то, что вы делаете, когда сортируете по номеру отдела, DEPTNO, и кажется маловероятным, что первичным ключом для сотрудника является номер его отдела.
дб <> рабочий пример здесь