Как получить данные слияния в Oracle - PullRequest
0 голосов
/ 14 мая 2018

У меня есть таблица SALARY_MASTER, которая содержит empid и salary. Ниже приведена структура таблицы.

EMPID   SALARY
------- ------
10001   12000
10002   60000
10003   25000
10004   35000
10005   15000
10006   24000
10007   85000
10008   75000
10009   65000
10010   67000
10011   95000
10012   23000
10013   48000
10014   25000
10015   35000

Другая таблица с именем SALARY_CURRENT с такими же столбцами. Ниже приведен пример данных.

EMPID   SALARY
------- ------
10001   24000
10003   36000
10005   23000
10007   99000
10009   79000
10016   52000
10017   98000
10018   63000
10019   77000
10020   47000
10021   35000

Эта таблица содержит обновленную зарплату для сотрудников. В каждом квартале я получаю эту таблицу от вышестоящих органов, и мне нужно обновлять таблицу SALARY_MASTER на основе таблицы SALARY_CURRENT. Поэтому я использовал команду merge в этом случае. Ниже мое merge утверждение:

MERGE into SALARY_MASTER SM
USING
    SALARY_CURRENT SC
ON
    (SM.EMPID = SC.EMPID)
WHEN MATCHED THEN
    UPDATE SET SM.SALARY = SC.SALARY
WHEN NOT MATCHED THEN
    INSERT (SM.EMPID,SM.SALARY) VALUES(SC.EMPID,SC.SALARY);

После слияния моего SALARY_MASTER таблица выглядит следующим образом:

EMPID   SALARY
------- ------
10001   24000
10002   60000
10003   36000
10004   35000
10005   23000
10006   24000
10007   99000
10008   75000
10009   79000
10010   67000
10011   95000
10012   23000
10013   48000
10014   25000
10015   35000
10016   52000
10017   98000
10018   63000
10019   77000
10020   47000
10021   35000

Я хочу только затронутые строки. Моя выходная таблица будет выглядеть так:

EMPID   SALARY  STATUS
------- ------- ------
10001   24000   UPDATE
10002   60000   NONE
10003   36000   UPDATE
10004   35000   NONE
10005   23000   UPDATE
10006   24000   NONE
10007   99000   UPDATE
10008   75000   NONE
10009   79000   UPDATE
10010   67000   NONE
10011   95000   NONE
10012   23000   NONE
10013   48000   NONE
10014   25000   NONE
10015   35000   NONE
10016   52000   INSERT
10017   98000   INSERT
10018   63000   INSERT
10019   77000   INSERT
10020   47000   INSERT
10021   35000   INSERT

Или:

EMPID   SALARY  STATUS
------- ------- ------
10001   24000   UPDATE
10003   36000   UPDATE
10005   23000   UPDATE
10007   99000   UPDATE
10009   79000   UPDATE
10016   52000   INSERT
10017   98000   INSERT
10018   63000   INSERT
10019   77000   INSERT
10020   47000   INSERT
10021   35000   INSERT

Я использую Oracle 11g. Фактическая таблица содержит более 300 тыс. Значений.

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Может быть, вы хотите иметь таблицу журнала для MERGE. Использование данных теста (имена таблиц изменены ...)

create table mergelog
as
select empid, salary, 'unchanged' as status
from salarymaster ;

Затем запустите MERGE, очень похожий на исходный, который изменяет данные в таблице журнала (ваши исходные таблицы остаются нетронутыми).

merge into mergelog M
using
  currentsalaries C
  on ( M.empid = C.empid )
when matched then
  update set 
    M.salary = C.salary
  , M.status = 'UPDATED'
  where M.salary <> C.salary
when not matched then
  insert ( M.empid, M.salary, M.status )
    values ( C.empid, C.salary, 'INSERTED' )
;

Таблица журнала теперь содержит ...

select * from mergelog order by empid ;

EMPID  SALARY  STATUS     
10001  24000   UPDATED    
10002  60000   unchanged  
10003  36000   UPDATED    
10004  35000   unchanged  
10005  23000   UPDATED    
10006  24000   unchanged  
10007  99000   UPDATED    
10008  75000   unchanged  
10009  79000   UPDATED    
10010  67000   unchanged  
10011  95000   unchanged  
10012  23000   unchanged  
10013  48000   unchanged  
10014  25000   unchanged  
10015  35000   unchanged  
10016  52000   INSERTED   
10017  98000   INSERTED   
10018  63000   INSERTED   
10019  77000   INSERTED   
10020  47000   INSERTED   
10021  35000   INSERTED   

21 rows selected.

Протестировано с Oracle 12c и 11g (см. dbfiddle.uk ).

0 голосов
/ 14 мая 2018

Используйте EXIST / NOT EXISTS with UNION, чтобы решить вашу проблему, проверьте код ниже:

select sm.empid,sm.salary,'UPDATE' status
from salary_master sm
where exists (select 1 from salary_current sc where sc.empid = sm.empid)
union
select sc.empid,sc.salary,'INSERT' status
from salary_current sc
where not exists (select 1 from salary_master sm where sm.empid = sc.empid);
...