如何在 Oracle 中获取合并数据
How to fetch merge data in Oracle
我有一个 table SALARY_MASTER,其中包含 empid
和 salary
。下面是 table 结构。
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
的 table 具有相同的列。以下是示例数据。
EMPID SALARY
------- ------
10001 24000
10003 36000
10005 23000
10007 99000
10009 79000
10016 52000
10017 98000
10018 63000
10019 77000
10020 47000
10021 35000
此 table 包含更新的员工薪水。在每个季度,我都从上级那里得到这个 table,我需要根据 SALARY_CURRENT
table 更新 SALARY_MASTER
table。所以我在这种情况下使用 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
后,table 如下所示:
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
我只想要受影响的行。我的输出 table 将如下所示:
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。实际 table 包含超过 300k 个值。
使用 EXIST/NOT EXISTS 和 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);
也许您想要 MERGE 的日志 table。
使用您的测试数据(table 名称已更改...)
create table mergelog
as
select empid, salary, 'unchanged' as status
from salarymaster ;
然后,运行 一个 MERGE,与你原来的非常相似,它修改日志中的数据 table(你原来的 tables 保持不变)。
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' )
;
日志 table 现在包含 ...
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)。
我有一个 table SALARY_MASTER,其中包含 empid
和 salary
。下面是 table 结构。
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
的 table 具有相同的列。以下是示例数据。
EMPID SALARY
------- ------
10001 24000
10003 36000
10005 23000
10007 99000
10009 79000
10016 52000
10017 98000
10018 63000
10019 77000
10020 47000
10021 35000
此 table 包含更新的员工薪水。在每个季度,我都从上级那里得到这个 table,我需要根据 SALARY_CURRENT
table 更新 SALARY_MASTER
table。所以我在这种情况下使用 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
后,table 如下所示:
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
我只想要受影响的行。我的输出 table 将如下所示:
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。实际 table 包含超过 300k 个值。
使用 EXIST/NOT EXISTS 和 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);
也许您想要 MERGE 的日志 table。 使用您的测试数据(table 名称已更改...)
create table mergelog
as
select empid, salary, 'unchanged' as status
from salarymaster ;
然后,运行 一个 MERGE,与你原来的非常相似,它修改日志中的数据 table(你原来的 tables 保持不变)。
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' )
;
日志 table 现在包含 ...
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)。