[英]Oracle, find differences in records between two "sets"
一些腳本:
create table set_1
( id number(12));
create table set_2
( id number(12));
create table map_set
( id_set_1 number(12),
id_set_2 number(12)
);
insert into set_1 values(1);
insert into set_1 values(2);
insert into set_1 values(3);
insert into set_1 values(4);
insert into map_set values(1,5);
insert into map_set values(2,6);
insert into map_set values(3,7);
insert into map_set values(4,8);
insert into set_2 values(5);
insert into set_2 values(6);
insert into set_2 values(7);
insert into set_2 values(8);
create table attrib_1(
id number(12),
set_id number(12),
attrib_id number(2),
val number(10,2));
create table attrib_2
(
id number(12),
set_id number(12),
attrib_id number(2),
val number(10,2)
);
insert into attrib_1 values(1,1,1,10.2);
insert into attrib_1 values(2,1,2,2.5);
insert into attrib_1 values(3,1,3,5.23);
SELECT * FROM attrib_1;
insert into attrib_2 values(1,5,2,4.54);
insert into attrib_2 values(2,5,3,89.5);
有一個 - 讓我們稱它們為集合。 還有一個映射此集合的表,因此在這種情況下,來自 set_1 表且 id = 1 的 fe set 是 id = 2 的 set_2 的副本。 集合可以有一個或多個屬性。 然后我們對該屬性集進行一些更改。
我想要的是檢測“相同”集合之間此屬性之間的差異。 我寫了這個:
SELECT *
FROM (
SELECT a1.id ,
a1.attrib_id,
a1.val ,
s1.id AS set_id,
mp.id_set_2
FROM set_1 s1,
map_Set mp,
attrib_1 a1
WHERE mp.id_set_1 = s1.id
AND s1.id = 1
and a1.set_id = S1.id
) s1
full join
(
SELECT a2.id ,
a2.attrib_id,
a2.val ,
s2.id AS set_id
FROM set_2 s2,
attrib_2 a2
WHERE s2.id = 5
and a2.set_id = S2.id
) s2
ON s1.id_set_2 = s2.set_id
AND s1.attrib_id = s2.attrib_id
我想創建for.. loop
plsql 代碼,它獲取所有記錄並且:
我需要一個 set 的 id 來執行 INSERT,但是沒有 id“empty attrib”記錄。
我希望 output 看起來像這樣:
我嘗試了左連接,這是我最接近我的目標但現在我被卡住了。
有任何想法嗎? 謝謝!
編輯:我更喜歡在一個 SQL 中執行此操作。表上的觸發器禁止在一個插入中對幾個 id 進行操作。
您要執行三個操作。 它們可以通過三個單獨的查詢來完成:
update (
select x.*, u.bval
from attrib_1 x
join (
select
m.*, a.attrib_id as aid, a.val as aval, b.val as bval
from map_set m
join attrib_1 a on a.set_id = m.id_set_1
full join attrib_2 b on b.set_id = m.id_set_2 and b.attrib_id = a.attrib_id
) u on u.aid = x.attrib_id and u.aval <> u.bval
)
set val = bval
delete from attrib_2
where (set_id, attrib_id) in (
select b.set_id, b.attrib_id
from map_set m
join attrib_1 a on a.set_id = m.id_set_1
right join attrib_2 b on b.set_id = m.id_set_2 and b.attrib_id = a.attrib_id
where a.set_id is null
);
insert into attrib_2 (id, set_id, attrib_id, val)
select
100, -- probably use an identity or sequence
m.id_set_2, a.attrib_id, a.val
from map_set m
join attrib_1 a on a.set_id = m.id_set_1
left join attrib_2 b on b.set_id = m.id_set_2 and b.attrib_id = a.attrib_id
where b.set_id is null
ID_SET_1 ID_SET_2 AID AVAL BVAL
--------- --------- ---- ----- ----
1 5 1 10.2 10.2
1 5 2 4.54 4.54
1 5 3 89.5 89.5
請參閱db<>fiddle中的運行示例。 我在您的示例中添加了一行以測試用例 #3(添加)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.