Предположим, что у вас есть некоторые примеры данных:
CREATE TABLE table_a ( Column_A, Column_B ) AS
SELECT 0, 'Descriptions' FROM DUAL UNION ALL
SELECT 100, 'Descriptions' FROM DUAL UNION ALL
SELECT 3, 'Range1' FROM DUAL UNION ALL
SELECT 5, 'Range2' FROM DUAL UNION ALL
SELECT 6, 'Range2' FROM DUAL UNION ALL
SELECT 7, 'Range2' FROM DUAL;
И вы хотите обновить Descriptions
, чтобы иметь диапазон от 1 до 10, а также хотите обновить Range1
, чтобы иметь диапазон от 42-50 (но в данных выборки есть только одна строка) и Range2
, чтобы иметь диапазон от 0 до 9 (но в данных выборки более двух строк). Тогда вы можете использовать оператор MERGE
:
MERGE INTO table_a dst
USING (
WITH ranges ( Column_A, Column_B, rn ) AS (
SELECT 1, 'Descriptions', 1 FROM DUAL UNION ALL
SELECT 10, 'Descriptions', 0 FROM DUAL UNION ALL
SELECT 42, 'Range1', 1 FROM DUAL UNION ALL
SELECT 50, 'Range1', 0 FROM DUAL UNION ALL
SELECT 0, 'Range2', 1 FROM DUAL UNION ALL
SELECT 9, 'Range2', 0 FROM DUAL
)
SELECT r.Column_A,
r.Column_B,
a.rid
FROM ranges r
LEFT OUTER JOIN (
SELECT ROWID AS rid,
ROW_NUMBER() OVER ( PARTITION BY Column_B ORDER BY ROWNUM ) AS rn,
Column_B
FROM table_a
) a
ON ( r.Column_B = a.Column_B AND MOD( a.rn, 2 ) = r.rn )
) src
ON ( src.rid = dst.ROWID )
WHEN MATCHED THEN
UPDATE SET Column_A = src.Column_A
WHEN NOT MATCHED THEN
INSERT ( Column_A, Column_B )
VALUES ( src.Column_A, src.Column_B );
И результат будет:
SELECT * FROM table_a;
COLUMN_A | COLUMN_B
-------: | :-----------
1 | Descriptions
10 | Descriptions
42 | Range1
0 | Range2
9 | Range2
0 | Range2
50 | Range1
Вы видите, что дополнительная строка для Range1
был создан и все строки для Range2
были обновлены.
db <> fiddle здесь