簡體   English   中英

Oracle,查找兩個“集合”之間的記錄差異

[英]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 代碼,它獲取所有記錄並且:

  • 如果 attrib_id 相同而 val 不同 - 更新記錄
  • 如果 set_2 中有屬性但 set_1 中缺少 - 刪除
  • 如果 set_1 中有 attrib 但 set_2 中缺少 - 添加,這就是問題所在:

在此處輸入圖像描述

我需要一個 set 的 id 來執行 INSERT,但是沒有 id“empty attrib”記錄。

我希望 output 看起來像這樣:

在此處輸入圖像描述

  • 擁有關於集合的所有數據,並左連接屬性。

我嘗試了左連接,這是我最接近我的目標但現在我被卡住了。

有任何想法嗎? 謝謝!

編輯:我更喜歡在一個 SQL 中執行此操作。表上的觸發器禁止在一個插入中對幾個 id 進行操作。

您要執行三個操作。 它們可以通過三個單獨的查詢來完成:

1. 如果 attrib_id 相同而 val 不同 - 更新記錄

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

2. 如果 set_2 中有 attrib 但 set_1 中缺少 - 刪除

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
);

3. 如果 set_1 中有 attrib 但 set_2 中缺少 - 添加

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM