簡體   English   中英

使用雙循環通過pl sql更新表過程

[英]Update table procedure through pl sql using double loop

假設我只有一個表:members_tbl,其中的列是:SN,FN,DB,IDDBL,FLAG,DBLCRIT,如果使用此算法可以滿足某些條件,我需要更新表:

   id_dup := 1;
FOR (i in 1 to Nrow(members_tbl)) THEN
{
FOR (j in (i+1) to Nrow(members_tbl)) THEN
{
IF(members_tbl(i).iddbl IS NULL) THEN
members_tbl(i).iddbl := id_dup
IF (((members_tbl(i).DBIRTH ==members_tbl(j).DBIRTH) AND
    (UTL_MATCH.jaro_winkler_similarity(members_tbl(i).SNAME,members_tbl(j).SNAME) > 80) AND
  (UTL_MATCH.jaro_winkler_similarity(members_tbl(i).FNAME,members_tbl(j).FNAME) > 80)) 
AND (members_tbl(j).iddbl IS NULL)) THEN
{
   members_tbl(j).iddbl := id_dup;
   members_tbl(i).flag := 1;
   members_tbl(j).flag := 1;
   members_tbl(i).dblcrit:= 1;
   members_tbl(j).dblcrit:= 1;
}

}
   id_dup := id_dup + 1;
}

這是一個測試用例:

CREATE TABLE MEMBERS_TBL
  (
    IDM     NUMBER(9) NOT NULL ,
    SNAME   VARCHAR2(20) ,
    FNAME   VARCHAR2(20) ,
    DBIRTH  VARCHAR2(15) ,
    IDDBL   NUMBER(10) ,
    FLAG    SMALLINT ,
    DBLCRIT SMALLINT
  );
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (125,'BOLOREY','JEANNE','11/05/1955',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (126,'BOLLOREY','JEANNE','11/05/1955',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (153,'BALORE','GIANNE','11/05/1955',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (223,'ABOLLOREYY','JEANNE','11/05/1955',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (225,'FIABLE','MARINE','25/04/1963',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (228,'FAIBLE','MARYANE','25/04/1963',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (230,'FAIBLE','MARINE','25/04/1963',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (235,'LIPARK','JACQLINE','20/12/1939',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (236,'ILIPARC','JACQUELYNE','20/12/1939',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (237,'LIPARC','JACQUELHINE','20/12/1939',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (240,'RINTET','MALIKA','07/08/1954',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (241,'GRISION','RAUGER','26/10/1931',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (242,'GRISION','ROGER','26/10/1931',NULL,NULL,NULL);
Insert into members_tbl (IDM,SNAME,FNAME,DBIRTH,IDDBL,FLAG,DBLCRIT) values (245,'GRESION','RAUJER','26/10/1931',NULL,NULL,NULL);

為了更全面,我確實更改了SNAME中的SN列,FNAME中的FN和DBIRTH中的DB

有沒有一種方法可以在pl / sql過程中編寫此算法? 我對PL / SQL相對較新,並且從未編寫過存儲過程。

我認為這會起作用。 您需要弄清楚它是如何確定哪一行是“較高”的,從而確定重復的。

update members_tbl
set iddbl = 1
where iddbl is null and exists (
    select 1
    from members_tbl m2
    where
            m2.DB = members_tbl.DB
        and UTL_MATCH.jaro_winkler_similarity(members_tbl.FN, m2.FN) > 80
        and UTL_MATCH.jaro_winkler_similarity(members_tbl.SN, m2.SN) > 80
        and NumberOfRow(m2) < NumberOfRow(members_tbl) /* ??? */

);

update members_tbl
set flag = 1, dblcrit = 1;

實際上,正如@ shawnt00所建議的那樣,它是基於Jaro Winkler函數對字符串近似的重復檢測。 因此,不需要計數(不需要標志,dblcrit,iddbl),只需左外連接:

SELECT * FROM (
SELECT m.IDM,
       m2.IDM AS dups_key
FROM members_tbl m
LEFT OUTER JOIN members_tbl m2
ON ( m.IDM != m2.IDM
      AND m.DBIRTH = m2.DBIRTH
      AND utl_match.jaro_winkler_similarity(m.SNAME,m2.SNAME) > 80
      AND utl_match.jaro_winkler_similarity(m.FNAME,m2.FNAME) > 80 )
    )
Where dups_key IS NOT NULL;

然后,如果我使用了前面提到的計數器,我還提取了我需要的其他信息。 因此,在以下鏈接中,這是從上面的第一個查詢中提取的其他數據: 此鏈接。

暫無
暫無

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

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