ORACLE SQL UPDATE 与 INNER JOIN 不起作用

Posted

技术标签:

【中文标题】ORACLE SQL UPDATE 与 INNER JOIN 不起作用【英文标题】:ORACLE SQL UPDATE with INNER JOIN isn't working 【发布时间】:2020-09-09 08:20:03 【问题描述】:

我目前正在学习 SQL,并且正在使用 ORACLE DATABASE。 我已经完成了这个网站的练习:https://sql.sh/exercices-sql/commandes 我正在做完全相同的事情,但这次是针对 Oracle 数据库。

我的问题如下:

我有这两张桌子:

CREATE TABLE orders(
  order_id INT GENERATED BY DEFAULT AS IDENTITY,
  customer_id INT NOT NULL,
  order_date DATE NOT NULL,
  reference VARCHAR(255) NOT NULL,
  total_price_cache DECIMAL(10, 3) NOT NULL,
  PRIMARY KEY(order_id)
);
CREATE TABLE order_lines(
  order_line_id INT GENERATED BY DEFAULT AS IDENTITY,
  order_id INT NOT NULL,
  name VARCHAR(255) NOT NULL,
  quantity INT NOT NULL,
  unit_price DECIMAL(10, 3) NOT NULL,
  total_price DECIMAL(10, 3) NOT NULL,
  PRIMARY KEY(order_line_id)
);

我正在尝试执行以下操作:

UPDATE orders AS t1 
INNER JOIN 
    ( SELECT order_id, SUM(order_lines.total_price) AS p_total 
      FROM order_lines 
      GROUP BY order_id ) t2 
          ON  t1.order_id = t2.order_id 
SET t1.total_price_cache = t2.p_total

我为 mysql 工作,但不为 Oracle 数据库工作。 我不断收到错误 ORA-00971 说关键字 SET 不存在。

谁能解释我如何为 Oracle 数据库执行此操作。

谢谢

【问题讨论】:

Oracle 更新不能那样工作。不能用as 表达式限定表,也不能使用内连接 这能回答你的问题吗? Update statement with inner join on Oracle 【参考方案1】:

Oracle 不支持这种 MySQL 风格的更新连接语法。但是,您可以改用相关子查询:

UPDATE orders AS o
SET total_price_cache = (SELECT SUM(total_price) FROM order_lines ol
                         WHERE ol.order_id = o.order_id);

【讨论】:

@GabrielKnies:这个解决方案可能比使用merge 语句的公认答案更有效,该语句在using 子句中有一个不必要的附加连接。 @GMB 您是否定期查看旧答案?【参考方案2】:

作为更新命令的替代,您可以使用merge 代替

merge into orders target 
using 
( SELECT t2.order_id , SUM(t2.total_price) AS p_total 
      FROM order_lines t2 inner join orders t1
      ON  t1.order_id = t2.order_id 
      GROUP BY t2.order_id ) source 
    on ( target.order_id = source.order_id ) 
when matched then 
update set target.total_price_cache = source.p_total

【讨论】:

【参考方案3】:

您可以将带有连接的 MYSQL 更新转换为 Oracle 中的 key preversed 视图

UPDATE (SELECT t1.total_price_cache AS total_price_cache,
                t1.order_id,
                t2.order_id
                orders AS t1 ,
                t2.p_total
                FROM orders AS t1
                INNER JOIN 
                ( SELECT order_id, SUM(order_lines.total_price) AS p_total 
                    FROM order_lines 
                    GROUP BY order_id ) t2 
                    ON  t1.order_id = t2.order_id )
SET t1.total_price_cache = t2.p_total

【讨论】:

以上是关于ORACLE SQL UPDATE 与 INNER JOIN 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

sql update__inner.sql

SQL UPDATE with INNER JOIN

INNER JOIN和IN的结合:Oracle Sql

Oracle SQL INNER Join 基于不匹配的值

在 Oracle SQL Query 中加入(INNER JOIN)本地 Excel 表 - VBA

oracle sql中的join关键字和inner join关键字有啥区别? [复制]