【问题标题】:ORACLE SQL UPDATE with INNER JOIN isn't workingORACLE SQL UPDATE 与 INNER JOIN 不起作用
【发布时间】: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 数据库执行此操作。

谢谢

【问题讨论】:

标签: sql oracle sql-update inner-join


【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多