簡體   English   中英

按 1 個字段連接 2 個表,在其他兩個字段上部分匹配 - 沒有笛卡爾積

[英]Join 2 tables by 1 field, partial matching on other two fields - no cartesian product

我有 2 個表,代表干預 (ID_TK) 中組件的替換,每個表都有一個零件號 OLD 和一個零件號 NEW,從兩個不同的系統角度(PN OLD 和 NEW 在一個系統中,HWC OLD 和 NEW 在一個系統中另一個)。

對於每個 ID_TK,兩個表中的行數可能不同。

ID_SOST 是第一個表中的唯一鍵,PR_ID 是第二個表中的唯一鍵。

但是,只有 id 干預 (ID_TK) 才能准確地鏈接兩個表。 我必須檢查每次干預的兩個表中的替換是否匹配。 “匹配”是指:相同的 ID_TK,AND PN_OLD 必須是 HWC_OLD 的子字符串(或等於),AND PN_NEW 必須是 HWC_NEW 的子字符串(或等於)(均為大寫):

case 
  when 
   (UPPER(PN_NEW) = UPPER(SUBSTR(HWC_NEW,1,LENGTH(PN_NEW))) AND UPPER(PN_OLD) = UPPER(SUBSTR(HWC_OLD,1,LENGTH(PN_OLD)))) THEN 'YES' else 'NO' as MATCH

在此處輸入圖片說明

在desiderata結果表中,必須首先列出“匹配”的夫婦ID_SOST-PR_ID,並且沒有考慮他們在ID_TK中的任何其他匹配(最好的選擇是精確匹配); 剩下的不匹配的夫婦必須在匹配的夫婦之后列出,首先列出更好的相似性。 困難在於我不想顯示非匹配替換(PR 和 ID_SOST)的笛卡爾積。 順便說一句,如果 PR(或 SOST)的數量不同,null 將填補缺失的字段。

首先,為了將來參考,以下是如何在問題中提供示例數據:

create table table1 (id_tk varchar2(20), id_sost varchar2(20), hwc_old varchar2(20), hwc_new varchar2(20));
create table table2 (id_tk varchar2(20), pr_id varchar2(20), pn_old varchar2(20), pn_new varchar2(20));

insert into table1 values ('TK0000001296676', '00000000199412', '3AL80407AA', '3AL80407AA');
insert into table1 values ('TK0000001296676', '00000000199413', '3AL79090BAAS', '3AL79090BAAS');

insert into table2 values ('TK0000001296676', 'pr-20191025-008', '3AL79090BAAS04', '3AL79090BA');
insert into table2 values ('TK0000001296676', 'pr-20191115-009', '3AL79090BA', '3AL79090BA');
insert into table2 values ('TK0000001296676', 'pr-20191115-011', '3AL79090BAAS04', '3AL79090BA');

這非常有幫助 - 請不要讓我們重新輸入您已有的文本。 只需從 Excel 復制/粘貼數據也可以。

對於實際查詢 - 我們正在執行完整的外部聯接,並且僅包括匹配或具有空值而不是匹配的行。 我們也可以把它寫成一個完整的外連接,不包括不匹配的笛卡爾積行。

select nvl(table1.id_tk, table2.id_tk) as id_tk, id_sost, hwc_old, hwc_new, pr_id, pn_old, pn_new,
    case when (UPPER(PN_NEW) = UPPER(SUBSTR(HWC_NEW,1,LENGTH(PN_NEW))) AND UPPER(PN_OLD) = UPPER(SUBSTR(HWC_OLD,1,LENGTH(PN_OLD)))) THEN 'YES' else 'NO' end as MATCH
from table1
full outer join table2
    on (table1.id_tk = table2.id_tk -- display matches if they exist
    and UPPER(PN_NEW) = UPPER(SUBSTR(HWC_NEW,1,LENGTH(PN_NEW))) 
    and UPPER(PN_OLD) = UPPER(SUBSTR(HWC_OLD,1,LENGTH(PN_OLD)))
    ) OR ( -- also include rows with no matches
        (id_sost is null or pr_id is null))
order by MATCH desc -- show matches first
;

輸出 - 我的輸出與您的有點不同,因為我認為您不會真的希望在同一行中包含不匹配的ID_SOST - PR_ID數據。 在SQL中很難做到,我認為這種方式更清楚行中的table1/table2數據彼此不匹配。

ID_TK           ID_SOST HWC_OLD         HWC_NEW         PR_ID           PN_OLD          PN_NEW      MATCH
TK0000001296676 199413  3AL79090BAAS    3AL79090BAAS    pr-20191115-009 3AL79090BA      3AL79090BA  YES
TK0000001296676 null    null            null            pr-20191115-011 3AL79090BAAS04  3AL79090BA  NO
TK0000001296676 null    null            null            pr-20191025-008 3AL79090BAAS04  3AL79090BA  NO
TK0000001296676 199412  3AL80407AA      3AL80407AA      null            null            null        NO

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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