Оператор MERGE
будет более эффективным, и вы, вероятно, должны его использовать;однако вы можете использовать:
UPDATE table1 t1
SET PHONE_NUMBER = NVL(
( SELECT t2.phone_number
FROM table2 t2
WHERE t1.id = t2.id ),
CASE
WHEN t1.type IN ( 'A', 'B' )
THEN NULL
ELSE t1.phone_number
END
)
WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE t1.id = t2.id );
Oracle Setup :
CREATE TABLE table1 ( id, phone_number, type ) AS
SELECT 1, 123456, 'A' FROM DUAL UNION ALL
SELECT 2, 123456, 'B' FROM DUAL UNION ALL
SELECT 3, 123456, 'C' FROM DUAL UNION ALL
SELECT 4, 123456, 'D' FROM DUAL UNION ALL
SELECT 5, 123456, 'E' FROM DUAL;
CREATE TABLE table2 ( id, phone_number ) AS
SELECT 1, 234567 FROM DUAL UNION ALL
SELECT 2, NULL FROM DUAL UNION ALL
SELECT 3, 345678 FROM DUAL UNION ALL
SELECT 4, NULL FROM DUAL;
Вывод :
После запусказатем обновите:
SELECT * FROM table1
Выводит то же самое, что и оператор MERGE
:
ID | PHONE_NUMBER | TYPE
-: | -----------: | :---
1 | 234567 | A
2 | <em>null</em> | B
3 | 345678 | C
4 | 123456 | D
5 | 123456 | E
db <> fiddle здесь
Обновление :
Если вы посмотрите на EXPLAIN PLAN
для оператора MERGE
:
| PLAN_TABLE_OUTPUT |
| :------------------------------------------------------------------------------ |
| Plan hash value: 3423411568 |
| |
| ------------------------------------------------------------------------------- |
| | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | |
| ------------------------------------------------------------------------------- |
| | 0 | MERGE STATEMENT | | 4 | 168 | 7 (15)| 00:00:01 | |
| | 1 | MERGE | TABLE1 | | | | | |
| | 2 | VIEW | | | | | | |
| |* 3 | HASH JOIN | | 4 | 268 | 7 (15)| 00:00:01 | |
| | 4 | TABLE ACCESS FULL| TABLE2 | 4 | 104 | 3 (0)| 00:00:01 | |
| | 5 | TABLE ACCESS FULL| TABLE1 | 5 | 205 | 3 (0)| 00:00:01 | |
| ------------------------------------------------------------------------------- >
Тогда он читает только TABLE1
и TABLE2
по одному разу.
Сравните это с EXPLAIN PLAN
для оператора UPDATE
:
| PLAN_TABLE_OUTPUT |
| :----------------------------------------------------------------------------- |
| Plan hash value: 735598124 |
| |
| ------------------------------------------------------------------------------ |
| | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | |
| ------------------------------------------------------------------------------ |
| | 0 | UPDATE STATEMENT | | 4 | 168 | 23 (22)| 00:00:01 | |
| | 1 | UPDATE | TABLE1 | | | | | |
| |* 2 | HASH JOIN SEMI | | 4 | 168 | 7 (15)| 00:00:01 | |
| | 3 | TABLE ACCESS FULL| TABLE1 | 5 | 145 | 3 (0)| 00:00:01 | |
| | 4 | TABLE ACCESS FULL| TABLE2 | 4 | 52 | 3 (0)| 00:00:01 | |
| |* 5 | TABLE ACCESS FULL | TABLE2 | 1 | 26 | 3 (0)| 00:00:01 | |
| ------------------------------------------------------------------------------ |
Затем он будет читать из TABLE1
один раз и TABLE2
дважды;так что MERGE
, вероятно, будет более производительным запросом .... но вы можете сделать это с UPDATE
, если хотите.
db <> fiddle здесь