Как обновить следующую таблицу с помощью MERGE в Oracle? - PullRequest
0 голосов
/ 25 октября 2018

У меня есть следующий набор данных (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.COLK, X.COLP, B.COLX, B.COLW

Конечной целью является выполнение следующих условий:

  • Если в таблице A более одной записи, где A.COL1и A.COL3 совпадают (и в таблице X есть соответствующая запись)
  • И одна из строк не равна нулю, например, A.COL4 = B, а другая - NULL

Я обновляю таблицу X, чтобы заменить X.COLK, X.COLP (K1 и 777) в моем операторе MERGE на значения в таблице B (B.COLX, B.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 голосов
/ 26 октября 2018

Вы можете сделать 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;

Демо

...