sql >> Databáze >  >> RDS >> Oracle

Příkaz aktualizace Oracle se skupinovou funkcí

V každé tabulce máte dva záznamy, kde area je 01 a musíte je nastavit na různé hodnoty, aby vyhovovaly primárnímu klíči – nemůžete je oba nastavit na maximální nebo minimální hodnotu z druhé tabulky, takže ve skutečnosti nechcete dělat žádné seskupování.

Zdá se, že mezi záznamy se stejnou area neexistuje žádné jiné řazení , takže budu předpokládat, že je to libovolné a nezáleží na tom, který záznam pro každou area získá který branch_code z druhého stolu. Pokud to není libovolné, pak by bylo potřeba specifikovat pravidla...

Korelovaná aktualizace je ošidná, pokud potřebujete porovnat v libovolném pořadí ve skupině záznamů. Potřebujete nějaký způsob, jak určit pořadí řádků, ale přidat row_number() sloupec k původním tabulkám za účelem vytvoření vloženého zobrazení povede k chybě ORA-01732.

Můžete však použít rowid cílové tabulky pseudosloupec; stačí provést další spojení v korelaci, abyste získali stejnou hodnotu spolu s novým branch_code . Něco jako:

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ž vám dává:

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           

Nyní ve skutečnosti nepotřebujete všechny tyto sloupce, potřebujete pouze rid (branch_cp.rowid ) a související branch_cp_2.branch_code .

Ale také chcete aktualizovat pouze v případě shody - abyste zrušili nulování všech řádků, kde v druhé tabulce není žádná hodnota - takže byste museli toto spojení opakovat v exists dílčí dotaz.

Je jednodušší provést 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.

Váš stůl nyní obsahuje:

select * from branch_cp;

AREA  BRANCH_CODE BRANCH_NAME
----- ----------- -----------
01    04          A           
01    05          B           
03    06          C           

SQL Fiddle .




  1. Pochopení systémových sloupců v PostgreSQL

  2. Syntaxe pro vstupní parametry v dotazu MySQL

  3. Funkce IIf() vs. Příkaz IIf().

  4. Postgres LIKE s hodnotou sloupce jako podřetězcem