如何在Oracle SQL中交换记录值?

the*_*rin 4 sql oracle

我应该为来自一组城市的来回飞行的航班号翻转航班号,例如:

1439 ATL SFO
1440 SFO ATL

最终会:

1440 ATL SFO
1439 SFO ATL

我试过这个查询(因为你不能在Oracle中更新..加入):

UPDATE
   (SELECT f.airline, f.flightno flightno_f, d.airline, d.flightno flightno_d
       FROM flights f
       INNER JOIN flights d ON f.airline = 9 AND
         f.sourceairport = d.destairport AND
         f.destairport = d.sourceairport AND d.airline = 9
       WHERE d.flightno < f.flightno) g
   SET g.flightno_f = g.flightno_d,
     g.flightno_d = g.flightno_f;
Run Code Online (Sandbox Code Playgroud)

航空公司,flightno是表航班的主要钥匙.select给了我想要交换的正确记录集,但是UPDATE ... SET给了我这个错误:

   SET g.flightno_f = g.flightno_d,
       *
ERROR at line 7:
ORA-01779: cannot modify a column which maps to a non key-preserved table
Run Code Online (Sandbox Code Playgroud)

关于我哪里出错的任何想法?

Dav*_*sta 5

为了更新连接,您选择的数据集恰好是密钥保留的并不重要; Oracle必须能够从约束和谓词中看出它将根据定义进行密钥保留.并且因为您在flightnumber上存在不等式条件,所以数据定义中没有任何内容可以保证您不会为给定的源行提供多个匹配项.

如果保证航班号总是相差1,那么如果将条件更改为,则可以使用连接方法d.flightno + 1 = f.flightno.

在任何情况下,我认为以下内容将起作用...由于语句级读取一致性,子查询应该返回正确的结果,即使行更新.

UPDATE flights f1
  SET flightno =
    (SELECT flightno
       FROM flights f2
       WHERE f2.airline = f1.airline
         AND f2.sourceairport = f1.destairport
         AND f2.destairport = f1.sourceairport
    )
  WHERE airline = 9;
Run Code Online (Sandbox Code Playgroud)