Oracle
 sql >> база данни >  >> RDS >> Oracle

Изявление за актуализиране на Oracle с групова функция

Имате два записа във всяка таблица, където area е 01 и трябва да ги зададете на различни стойности, за да удовлетворите първичния ключ - не можете да ги зададете и двете на максимална или минимална стойност от втората таблица, така че всъщност не искате да правите групиране.

Изглежда, че няма друго подреждане между записи с една и съща area , така че ще приема, че е произволно и няма значение кой запис за всяка area получава кой branch_code от другата маса. Ако не е произволно, тогава правилата трябва да бъдат посочени...

Корелираната актуализация е трудна, ако трябва да съвпаднете в произволен ред в рамките на група записи. Имате нужда от някакъв начин да идентифицирате реда на редовете, но добавяне на row_number() колона към оригиналните таблици за създаване на вграден изглед ще доведе до грешка ORA-01732.

Можете обаче да използвате rowid на целевата таблица псевдоколона; просто трябва да направите допълнително присъединяване в корелацията, за да получите същата стойност заедно с новия branch_code . Нещо като:

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;

Което ви дава:

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           

Сега всъщност нямате нужда от всички тези колони, имате нужда само от rid (branch_cp.rowid ) и корелирания branch_cp_2.branch_code .

Но също така искате да актуализирате само когато има съвпадение - за да анулирате нулирането на всички редове, където няма стойност в другата таблица - така че ще трябва да повторите това присъединяване в exists подзаявка.

По-лесно е да направите 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.

Вашата таблица вече има:

select * from branch_cp;

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

SQL Fiddle .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. използване на изхода на курсора в select

  2. Как да изляза от скрипт в SQLPlus, когато възникне грешка и да се върна към подканата SQLPlus, без да прекъсвам връзката или да излизам от SQLPlus?

  3. низовият литерал е твърде дълъг - как да присвоите дълги xml данни към типа данни clob в oracle 11g r2

  4. PLS-00103 създаване на външна таблица с динамичен SQL

  5. Преобразуване на целочислена стойност от db колона в текст в Oracle