如何在Oracle中使用MERGE更新下表?

时间:2018-10-25 20:09:58

标签: sql oracle merge sql-update oracle12c

我有以下数据集(Oracle 12):

Table X
+---------+--------+---------------+--------+
| COLN    | COLM   | COLK          | COLP   |
+---------+--------+---------------+--------+
| 1       | 500    | K1            | 777    |
+---------+--------+---------------+--------+

Table A
+---------+--------+---------------+--------+
| COL1    | COL2   | COL3          | COL4   |
+---------+--------+---------------+--------+
| 1       | K1     | 500           | B      |
| 1       | K2     | 500           | NULL   |
+---------+--------+---------------+--------+

Table B
+---------+--------+---------+
| COLZ    | COLX   | COLW    |
+---------+--------+---------+
| 1       | K1     | 777     |
| 1       | K2     | 678     |
+---------+--------+---------+

这三个表具有以下共同点:

X.COLN = A.COL1 = B.COLZ X.COLk = A.COL2 = B.COLX X.COLM = A.COL3

我需要编写一个查询,以在一个查询中检索以下列的值:

X.COLKX.COLPB.COLXB.COLW

最终目标是,如果满足以下条件:

  • 如果表A中有多个记录,其中A.COL1A.COL3匹配(并且表X中有对应的记录)
  • 并且其中一行不为null,例如A.COL4 = B,另一个是NULL

我更新表X,以将我的X.COLK语句中的X.COLPMERGE(K1和777)替换为表B中的值(B.COLXB.COLW -K2和678)。

这可能吗?

MERGE INTO X FX
USING (
    SELECT COLX ONGOING_X, COLW ONGOING_W 
    FROM B 
    WHERE (COLZ, COLX) IN 
        (SELECT COL1, COL2 
         FROM A 
         WHERE COL3 = ? 
            AND COL1 = ? 
            AND COL4 IS NULL)
) NEW_B
    ON (FX.COLk = ?
        AND FX.COLP = ?)
WHEN MATCHED THEN
    UPDATE SET
        FX.COLk = NEW_B.ONGOING_X,
        FX.FOLP = NEW_B.ONGOING_W;

1 个答案:

答案 0 :(得分:0)

您可以使用MERGE来进行ROWID

MERGE INTO x tgt USING (
     WITH c AS (
          SELECT col1,
                 col3,
                 MAX(
                      CASE
                           WHEN col4 IS NULL THEN col2
                      END
                 ) AS col2 --Ongoing col2 as indicated from col4
          FROM a
          GROUP BY col1,
                   col3
          HAVING COUNT(
               CASE
                    WHEN col4 IS NULL THEN 1
               END
          ) = 1 AND COUNT(col4) = 1 --Contains one and exactly one NULL and one NON NULL
     ) SELECT x.rowid AS rid,
              b.*
       FROM x
       JOIN c ON c.col1 = x.coln AND c.col3 = x.colm 
       JOIN b ON b.colz = c.col1 AND b.colx = c.col2 --Join with ongoing value from c( a.k.a table A )
)
src ON ( tgt.rowid = src.rid ) --ROWID match
WHEN MATCHED THEN UPDATE SET tgt.colk = src.colx,
tgt.colp = src.colw;

Demo