Совпадение немного разных записей в поле - PullRequest
0 голосов
/ 04 мая 2020

У меня ниже таблица есть. Как я могу go получить результаты в «ХОЧУ»? Я буду признателен за идеи, и я открыт для любого алгоритма нечеткого совпадения

Имею

ID Name   
1  Davi  
2  David 
3  DAVID
4  Micheal
5  Michael
6  Oracle
7  Tepper

ХОЧУ

ID Name mtch_ind  
1  Davi     1
2  David    1
3  DAVID    1
4  Micheal  2
5  Michael  2
6  Oracle   3
7 Tepper    4

TABLE DDL и вставку записи

CREATE TABLE HAVE (
  ID INTEGER,
  Name VARCHAR(10)
);

INSERT INTO data VALUES ('1', 'Davi');
INSERT INTO data VALUES ('2', 'David');
INSERT INTO data VALUES ('3', 'DAVID');
INSERT INTO data VALUES ('4', 'Micheal');
INSERT INTO data VALUES ('5', 'Michael');
INSERT INTO data VALUES ('6', 'Oracle');
INSERT INTO data VALUES ('7', 'Tepper');

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Хотя это решение немного некрасиво, я придумала этот подход. К вашему сведению, лучше всего сначала преобразовать прописную букву DAVID в David. Надеюсь, кто-то может найти это полезным или придумать лучшее решение. Спасибо

with table1 as (
SELECT ROW_NUMBER() OVER (ORDER BY firstID) as rowno,A.* FROM (
select 
t1.name
,t1.ID
, case when t1.ID>t1.Fid then fid else T1.ID end as FIRSTID 
, case when t1.ID>t1.Fid then T1.id else fID end as SECONDID 
, case when t1.ID>t1.Fid then t1.NAME else t1.FNAME end as FIRSTNAME
, case when t1.ID>t1.Fid then t1.FNAME  else t1.NAME  end as SECONDNAME
, case when count(*) over (partition by id) =1 then 'nodups' else 'dups' end as ID_chk
from (
SELECT h1.NAME,
 h1.ID, 
  h2.id as Fid,
  h2.name as Fname,
SYS.UTL_MATCH.JARO_WINKLER_SIMILARITY(h1.name,h2.name) as match1 
FROM (select 
NAME,
 ID from HAVE)h1 , (
select 
 NAME,
 ID FROM
have)
h2 where SYS.UTL_MATCH.JARO_WINKLER_SIMILARITY((h1.name),(h2.name)) > 75
order by h1.id
)
t1

)A
)
, no_dups as
(
select * from table1 where ID_chk='nodups'
)
,dups as
(
select * from table1 where ID_chk<>'nodups'
)
, dups_stp1 as
(
select * from dups
WHERE FIRSTID <>  SECONDID
)
, dups_stp2 as 
(
select rowno,ID,FIRSTID,SECONDNAME from dups_stp1 
where FIRSTID not in (select SECONDID from dups_stp1)
)

  select t2.ID,t3.NAME,rnk as mtch_ind  from (
select ID,SECONDNAME as NAME, dense_rank() OVER ( ORDER BY SECONDNAME asc)as rnk from (
select distinct ID, FIRSTID, SECONDNAME  from dups_stp2
union all 
select ID, FIRSTID, SECONDNAME  from no_dups
)t1 
)t2
inner join HAVE t3 on t2.ID=t3.ID
;

Ссылка https://www.decisivedata.net/blog/cleaning-messy-data-sql-part-1-fuzzy-matching-names

0 голосов
/ 04 мая 2020

Вот аль go, который, по моему мнению, должен работать:

Шаг 1: Определить близкие совпадения, используя ближайшее совпадение Джаро Винклера с пороговой математикой 75%, выберите h1.name h2.name , UTL_MATCH.JARO_WINKLER (h1.name, h2.name), поскольку match_confidence из соединения h1 имеет h2 для UTL_MATCH.JARO_WINKLER (h1.name, h2.name)> 0,75 - учитывая порог совпадения 75%. введите описание изображения здесь

Шаг 2: Выберите h2.name, где match_confidence является максимальным или одну верхнюю строку для похожих записей

, например [введите описание изображения здесь] [введите описание изображения здесь] 2

Шаг 3: выполните операцию плотного ранга в новом столбце, чтобы получить желаемый результат.

Надеюсь, это сработает Примечание: первый пост на SO. У меня нет доступа к oracle на данный момент.

...