W każdej tabeli masz dwa rekordy, w których area
to 01
, i musisz ustawić je na różne wartości, aby spełnić klucz podstawowy — nie możesz ustawić ich obu na maksymalną lub minimalną wartość z drugiej tabeli, więc tak naprawdę nie chcesz robić żadnego grupowania.
Wygląda na to, że nie ma innej kolejności między rekordami o tym samym area
, więc zakładam, że jest to arbitralne i nie ma znaczenia, który rekord dla każdego area
pobiera który branch_code
z drugiego stołu. Jeśli nie jest to arbitralne, należy określić zasady...
Skorelowana aktualizacja jest trudna, jeśli trzeba dopasować dowolną kolejność w grupie rekordów. Potrzebujesz sposobu na zidentyfikowanie kolejności wierszy, ale dodanie row_number()
kolumna do oryginalnych tabel, aby utworzyć widok wbudowany, spowoduje błąd ORA-01732.
Możesz jednak użyć rowid
tabeli docelowej pseudokolumna; wystarczy wykonać dodatkowe sprzężenie w korelacji, aby uzyskać tę samą wartość wraz z nowym branch_code
. Coś takiego:
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;
Co daje:
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
Teraz tak naprawdę nie potrzebujesz wszystkich tych kolumn, potrzebujesz tylko rid
(branch_cp.rowid
) i skorelowany branch_cp_2.branch_code
.
Ale chcesz również aktualizować tylko wtedy, gdy istnieje dopasowanie - aby unieważnić wszystkie wiersze, w których nie ma wartości w drugiej tabeli - więc będziesz musiał powtórzyć to złączenie w exists
podzapytanie.
Łatwiej jest wykonać 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.
Twój stół ma teraz:
select * from branch_cp;
AREA BRANCH_CODE BRANCH_NAME
----- ----------- -----------
01 04 A
01 05 B
03 06 C