Hai due record in ogni tabella dove area
è 01
e devi impostarli su valori diversi per soddisfare la chiave primaria:non puoi impostarli entrambi sul valore massimo o minimo dalla seconda tabella, quindi non vuoi davvero fare alcun raggruppamento.
Non sembra esserci nessun altro ordinamento tra record con la stessa area
, quindi presumo che sia arbitrario e non importa quale record per ciascuna area
ottiene quale branch_code
dall'altro tavolo. Se non è arbitrario, allora le regole dovrebbero essere specificate...
Un aggiornamento correlato è complicato se è necessario eseguire una corrispondenza su un ordine arbitrario all'interno di un gruppo di record. Hai bisogno di un modo per identificare l'ordine delle righe, ma aggiungendo un row_number()
colonna alle tabelle originali per creare una vista in linea comporterà un errore ORA-01732.
Tuttavia, puoi utilizzare il rowid
della tabella di destinazione pseudocolonna; devi solo fare un ulteriore join nella correlazione per ottenere lo stesso valore insieme al nuovo branch_code
. Qualcosa come:
select bc.rid,
bc.area,
bc.branch_code,
bc.branch_name,
bc2.area,
bc2.branch_code,
bc2.branch_name
from (
select bc.*,
bc.rowid as rid,
row_number() over (partition by bc.area order by bc.branch_code) as rn
from branch_cp bc
) bc
join (
select bc2.*,
row_number() over (partition by bc2.area order by bc2.branch_code) as rn
from branch_cp_2 bc2
) bc2
on bc2.area = bc.area
and bc2.rn = bc.rn;
Che ti dà:
RID AREA BRANCH_CODE BRANCH_NAME AREA BRANCH_CODE BRANCH_NAME
------------------ ----- ----------- ----------- ----- ----------- -----------
AAAwy+AAEAAAA0DAAA 01 01 A 01 04 D
AAAwy+AAEAAAA0DAAB 01 02 B 01 05 E
AAAwy+AAEAAAA0DAAC 03 03 C 03 06 F
Ora in realtà non hai bisogno di tutte quelle colonne, hai solo bisogno del rid
(il branch_cp.rowid
) e il correlato branch_cp_2.branch_code
.
Ma vuoi anche aggiornare solo quando c'è una corrispondenza - per annullare l'annullamento di qualsiasi riga in cui non c'è alcun valore nell'altra tabella - quindi dovresti ripetere quel join in exists
sottoquery.
È più semplice eseguire un merge
:
merge into branch_cp bc
using (
select bc.rid,
bc2.branch_code
from (
select bc.*,
bc.rowid as rid,
row_number() over (partition by bc.area order by bc.branch_code) as rn
from branch_cp bc
) bc
join (
select bc2.*,
row_number() over (partition by bc2.area order by bc2.branch_code) as rn
from branch_cp_2 bc2
) bc2
on bc2.area = bc.area
and bc2.rn = bc.rn
) bc2
on (bc.rowid = bc2.rid)
when matched then update set bc.branch_code = bc2.branch_code;
3 rows merged.
La tua tabella ora ha:
select * from branch_cp;
AREA BRANCH_CODE BRANCH_NAME
----- ----------- -----------
01 04 A
01 05 B
03 06 C