[英]How to get an accurate JOIN using Fuzzy matching in Oracle
我正在嘗試從另一個表中的一個帶有縣名的表中加入一組縣名。 這里的問題是,兩個表中的縣名都沒有標准化。 它們的數量不一樣; 此外,他們可能不會總是以類似的模式出現。 例如,“表A”中的縣“SAINT JOHNS”可以在“表B”中表示為“ST JOHNS”。 我們無法預測它們的共同模式。
這意味着,我們不能在加入時使用“等於”( =
)條件。 所以,我正在嘗試使用oracle中的JARO_WINKLER_SIMILARITY
函數加入它們。 我的左外連接條件如下:
Table_A.State = Table_B.State
AND UTL_MATCH.JARO_WINKLER_SIMILARITY(Table_A.County_Name,Table_B.County_Name)>=80
在對結果進行一些測試后,我給出了測量值80,它似乎是最佳的。 在這里,問題是我在加入時會得到一組“誤報”。 例如,如果在同一狀態下有一些名稱具有相似性的縣(例如“BARRY”和“BAY”),如果度量>=80
,它們將匹配。這會產生不准確的連接數據集。任何人都可以請建議一些解決方法?
謝謝,DAV
你可以幫我構建一個查詢,查詢表B / C / D中每條記錄的Table_A,並匹配A中的縣名,其中排名最高的相似度> = 80
Oracle安裝程序 :
CREATE TABLE official_words ( word ) AS
SELECT 'SAINT JOHNS' FROM DUAL UNION ALL
SELECT 'MONTGOMERY' FROM DUAL UNION ALL
SELECT 'MONROE' FROM DUAL UNION ALL
SELECT 'SAINT JAMES' FROM DUAL UNION ALL
SELECT 'BOTANY BAY' FROM DUAL;
CREATE TABLE words_to_match ( word ) AS
SELECT 'SAINT JOHN' FROM DUAL UNION ALL
SELECT 'ST JAMES' FROM DUAL UNION ALL
SELECT 'MONTGOMERY BAY' FROM DUAL UNION ALL
SELECT 'MONROE ST' FROM DUAL;
查詢 :
SELECT *
FROM (
SELECT wtm.word,
ow.word AS official_word,
UTL_MATCH.JARO_WINKLER_SIMILARITY( wtm.word, ow.word ) AS similarity,
ROW_NUMBER() OVER ( PARTITION BY wtm.word ORDER BY UTL_MATCH.JARO_WINKLER_SIMILARITY( wtm.word, ow.word ) DESC ) AS rn
FROM words_to_match wtm
INNER JOIN
official_words ow
ON ( UTL_MATCH.JARO_WINKLER_SIMILARITY( wtm.word, ow.word )>=80 )
)
WHERE rn = 1;
輸出 :
WORD OFFICIAL_WO SIMILARITY RN
-------------- ----------- ---------- ----------
MONROE ST MONROE 93 1
MONTGOMERY BAY MONTGOMERY 94 1
SAINT JOHN SAINT JOHNS 98 1
ST JAMES SAINT JAMES 80 1
使用內聯的一些組成測試數據(您將使用自己的TABLE_A和TABLE_B代替前兩個with
子句,並從with matches as ...
開始with matches as ...
):
with table_a (state, county_name) as
( select 'A', 'ST JOHNS' from dual union all
select 'A', 'BARRY' from dual union all
select 'B', 'CHEESECAKE' from dual union all
select 'B', 'WAFFLES' from dual union all
select 'C', 'UMBRELLAS' from dual )
, table_b (state, county_name) as
( select 'A', 'SAINT JOHNS' from dual union all
select 'A', 'SAINT JOANS' from dual union all
select 'A', 'BARRY' from dual union all
select 'A', 'BARRIERS' from dual union all
select 'A', 'BANANA' from dual union all
select 'A', 'BANOFFEE' from dual union all
select 'B', 'CHEESE' from dual union all
select 'B', 'CHIPS' from dual union all
select 'B', 'CHICKENS' from dual union all
select 'B', 'WAFFLING' from dual union all
select 'B', 'KITTENS' from dual union all
select 'C', 'PUPPIES' from dual union all
select 'C', 'UMBRIA' from dual union all
select 'C', 'UMBRELLAS' from dual )
, matches as
( select a.state, a.county_name, b.county_name as matched_name
, utl_match.jaro_winkler_similarity(a.county_name,b.county_name) as score
from table_a a
join table_b b on b.state = a.state )
, ranked_matches as
( select m.*
, rank() over (partition by m.state, m.county_name order by m.score desc) as ranking
from matches m
where score > 50 )
select rm.state, rm.county_name, rm. matched_name, rm.score
from ranked_matches rm
where ranking = 1
order by 1,2;
結果:
STATE COUNTY_NAME MATCHED_NAME SCORE
----- ----------- ------------ ----------
A BARRY BARRY 100
A ST JOHNS SAINT JOHNS 80
B CHEESECAKE CHEESE 92
B WAFFLES WAFFLING 86
C UMBRELLAS UMBRELLAS 100
想法是matches
計算所有分數, ranked_matches
為它們分配一個序列( state
, county_name
),最終查詢選擇所有最高分數(即ranking = 1
過濾器ranking = 1
)。
你可能仍然會得到一些重復,因為沒有什么可以阻止兩個不同的模糊匹配得分相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.