如何使用子查询更新多行并在子查询中排序?
How to update multiple rows using a sub-query and order by in the sub-query?
我正在尝试使用子查询更新 table,但是子查询包含多个连接,因为我从多个 table 获取数据,并且作为业务需求,我我被迫在子查询中添加一个Order by以根据主键对元素进行排序,如果不添加order by则输出不准确。一个没有加入我想要做的事情的简单例子是:
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,那么我不会收到任何错误消息,但是我的结果不是预期的。我怎样才能做到这一点?
在相关 sub-query 的 outer-most sub-query 中使用 ORDER BY
从句在语法上是无效的,因为结果的顺序并不重要,因为应该仅是 sub-query 的单个匹配行。因此,您的问题的一般答案是不可能有 ORDER BY
子句,因为语法禁止它。
从 Oracle 12 开始,有一个例外允许在相关 sub-query 中使用 ORDER BY
子句,即当您还使用 FETCH FIRST ROW ONLY
来保证 sub-query returns只有一行。
因此,如果您为 sub-query 获取多行并且您只想要第一行,那么在 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
,并且员工的主键似乎不太可能是其部门编号。
db<>fiddle here
我正在尝试使用子查询更新 table,但是子查询包含多个连接,因为我从多个 table 获取数据,并且作为业务需求,我我被迫在子查询中添加一个Order by以根据主键对元素进行排序,如果不添加order by则输出不准确。一个没有加入我想要做的事情的简单例子是:
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,那么我不会收到任何错误消息,但是我的结果不是预期的。我怎样才能做到这一点?
在相关 sub-query 的 outer-most sub-query 中使用 ORDER BY
从句在语法上是无效的,因为结果的顺序并不重要,因为应该仅是 sub-query 的单个匹配行。因此,您的问题的一般答案是不可能有 ORDER BY
子句,因为语法禁止它。
从 Oracle 12 开始,有一个例外允许在相关 sub-query 中使用 ORDER BY
子句,即当您还使用 FETCH FIRST ROW ONLY
来保证 sub-query returns只有一行。
因此,如果您为 sub-query 获取多行并且您只想要第一行,那么在 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
,并且员工的主键似乎不太可能是其部门编号。
db<>fiddle here