The MERGE
statement is going to be more efficient and you should probably use that; however, you could use:
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;
Output:
After running the update then:
SELECT * FROM table1
Outputs the same as the MERGE
statement:
ID | PHONE_NUMBER | TYPE
-: | -----------: | :---
1 | 234567 | A
2 | null | B
3 | 345678 | C
4 | 123456 | D
5 | 123456 | E
db<>fiddle here
Update:
If you look at the EXPLAIN PLAN
for the MERGE
statement:
| 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 | |
| ------------------------------------------------------------------------------- >
Then it only reads TABLE1
and TABLE2
once each.
Compare that to the EXPLAIN PLAN
for the UPDATE
statement:
| 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 | |
| ------------------------------------------------------------------------------ |
Then it will read from TABLE1
once and TABLE2
twice; so the MERGE
is likely to be a more performant query.... but you can do it with an UPDATE
if you want.
db<>fiddle here