[英]SYNC and UPDATE at the same time between two tables in Oracle SQL
我在ORACLE SQL操作上遇到麻烦。 首先,我有两个表
TEST_TABLE_A
Insert into TEST_TABLE_A (NAME, VAL1, VAL2, STATUS) Values ('HEAD1', 100, 200, 'ACTIVE');
Insert into TEST_TABLE_A (NAME, VAL1, VAL2, STATUS) Values ('HEAD2', 300, 400, 'ACTIVE');
Insert into TEST_TABLE_A (NAME, VAL1, VAL2, STATUS) Values ('HEAD3', 500, 600, 'ACTIVE');
Insert into TEST_TABLE_A (NAME, VAL1, VAL2, STATUS) Values ('HEAD4', 700, 800, 'ACTIVE');
TEST_TABLE_B
Insert into TEST_TABLE_B (NAME, VAL1, VAL2) Values ('HEAD1', 1, 2);
Insert into TEST_TABLE_B (NAME, VAL1, VAL2) Values ('HEAD4', 700, 800);
Insert into TEST_TABLE_B (NAME, VAL1, VAL2) Values ('HEAD5', 900, 1000);
我的任务列出如下:1.将数据从表b同步到表a 2.当找到具有相同值的相同名称时,将其忽略3.当找到具有不同值的相同名称时,将具有相同值的数据插入表A名称和从B获取的值,并用“ INACTIVE”状态更新旧行4.当在基于表B的表A中找不到数据时,将数据插入表A
我的查询是这样的
MERGE INTO TEST_TABLE_A TGT
USING TEST_TABLE_B SRC
ON (TGT.NAME = SRC.NAME)
WHEN MATCHED THEN
UPDATE SET TGT.VAL1 = SRC.VAL1,
TGT.VAL2 = SRC.VAL2
WHEN NOT MATCHED THEN
INSERT (TGT.NAME, TGT.VAL1, TGT.VAL2, TGT.STATUS)
VALUES (SRC.NAME, SRC.VAL1, SRC.VAL2, 'ACTIVE');
所以我面临着我无法使#3工作的问题。 我尝试了SQL的许多组合,但它并没有起作用。
我如何通过忽略两个表中具有相同值的相同名称来使2号工作?
我希望结果会像这样
TEST_TABLE_A
NAME VAL1 VAL2 STATUS
-----------------------------
HEAD1 100 200 INACTIVE
HEAD1 1 2 ACTIVE
HEAD2 300 400 INACTIVE
HEAD3 500 600 INACTIVE
HEAD4 700 800 ACTIVE
HEAD5 900 1000 ACTIVE
我真的很感谢你们的帮助。 问候
试试这个:
如果HEAD2和HEAD3不活跃
--> Update the data that does not exist in table BLE_B to be INACTIVE
Update BLE_A
Set STATUS = 'INACTIVE'
From BLE_A a
Left Join BLE_B b
On b.Name = a.Name
And b.Val1 = a.Val1
And b.Val2 = a.Val2
Where b.Name is Null
--> Insert the data from BLE_B that does not exist in table BLE_A
--> or insert the data that different values with table BLE_A
Insert Into BLE_A
Select b.*, 'ACTIVE'
From BLE_B b
Left Join BLE_A a
On a.Name = b.Name
And a.Val1 = b.Val1
And a.Val2 = b.Val2
Where b.Name is Null
您不能仅对#3使用一次合并,因为您需要在相同的ON条件下进行更新和插入。
update test_table_a a set a.status = 'INACTIVE'
where exists (select 1 from test_table_b b
where b.name = a.name and (b.val1 != a.val1 or b.val2 != a.val2));
merge into test_table_a a using test_table_b b on (b.val1 = a.val1 and b.val2 = a.val2)
when not matched then insert values (b.name, b.val1, b.val2, 'ACTIVE');
但是我不明白为什么在您的输出中HEAD2和HEAD3处于“ INACTIVE”状态。 也许您还需要将TEST_TABLE_A中不存在的TEST_TABLE_A中的行标记为'INACTIVE'(在这种情况下,您可以通过添加以下条件来更改第一个更新:“或不存在(从test_table_b b中选择1,其中b.name = a.name)“)
我希望结果会像这样
TEST_TABLE_A
NAME VAL1 VAL2 STATUS
-----------------------------
HEAD1 100 200 INACTIVE
HEAD1 1 2 ACTIVE
HEAD2 300 400 INACTIVE
HEAD3 500 600 INACTIVE
HEAD4 700 800 ACTIVE
HEAD5 900 1000 ACTIVE
好的,让我们看一下如何满足SQL的每个规则。
1.第一件事只是两个表的简单UNION
。
2.然后,需要除去在NAME
, VAL1
和VAL2
列上重复的行。 因此,请使用ROW_NUMBER
分析。
3最后,选择RANK
为1。
SQL> SELECT name,
2 val1,
3 val2,
4 status
5 FROM
6 (SELECT a.*,
7 row_number() over(partition BY a.val1, a.val2 order by a.name, a.val1, a.val2) rn
8 FROM
9 ( SELECT name, val1, val2,'INACTIVE' status FROM TEST_TABLE_A
10 UNION
11 SELECT b.*, 'ACTIVE' status FROM TEST_TABLE_B b ORDER BY 1
12 ) A
13 )
14 WHERE rn = 1
15 /
NAME VAL1 VAL2 STATUS
-------------------- ---------- ---------- --------
HEAD1 1 2 ACTIVE
HEAD1 100 200 INACTIVE
HEAD2 300 400 INACTIVE
HEAD3 500 600 INACTIVE
HEAD4 700 800 ACTIVE
HEAD5 900 1000 ACTIVE
6 rows selected.
SQL>
因此,这正是您想要的输出。
*更新**根据OP的要求添加测试用例
SQL> SELECT * FROM test_table_a;
NAME VAL1 VAL2 STATUS
-------------------- ---------- ---------- --------------------
HEAD1 100 200 ACTIVE
HEAD2 300 400 ACTIVE
HEAD3 500 600 ACTIVE
HEAD4 700 800 ACTIVE
SQL>
SQL> CREATE TABLE test_table_a_new AS
2 SELECT name,
3 val1,
4 val2,
5 status
6 FROM
7 (SELECT a.*,
8 row_number() over(partition BY a.val1, a.val2 order by a.name, a.val1, a.val2) rn
9 FROM
10 ( SELECT name, val1, val2,'INACTIVE' status FROM TEST_TABLE_A
11 UNION
12 SELECT b.*, 'ACTIVE' status FROM TEST_TABLE_B b ORDER BY 1
13 ) A
14 )
15 WHERE rn = 1
16 /
Table created.
SQL>
SQL> DROP TABLE test_table_a PURGE
2 /
Table dropped.
SQL>
SQL> alter table test_table_a_new rename to test_table_a
2 /
Table altered.
SQL> select * from test_table_a
2 /
NAME VAL1 VAL2 STATUS
-------------------- ---------- ---------- --------
HEAD1 1 2 ACTIVE
HEAD1 100 200 INACTIVE
HEAD2 300 400 INACTIVE
HEAD3 500 600 INACTIVE
HEAD4 700 800 ACTIVE
HEAD5 900 1000 ACTIVE
6 rows selected.
SQL>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.