如何基于非精确匹配列实现表关联(规避Levenshtein算法)
解决带拼写差异的街道字段表关联问题(不用Levenshtein算法)
如果Levenshtein算法太耗时,试试下面这些更高效的实用方案:
1. 语音匹配函数(SOUNDEX/Metaphone)
很多拼写错误源于发音相近,语音匹配函数能把字符串转换成代表发音的编码,发音接近的字符串编码一致,匹配速度快。
用SOUNDEX的SQL示例:
SELECT t1.city, t2.fruit FROM table1 t1 JOIN table2 t2 ON SOUNDEX(t1.street_1) = SOUNDEX(t2.street_2)
如果担心纯语音匹配精度不够,可结合门牌号前缀精确匹配:
SELECT t1.city, t2.fruit FROM table1 t1 JOIN table2 t2 ON LEFT(t1.street_1, 4) = LEFT(t2.street_2, 4) -- 匹配开头门牌号 AND SOUNDEX(SUBSTRING(t1.street_1, 5)) = SOUNDEX(SUBSTRING(t2.street_2, 5)) -- 匹配街道名发音
2. 字符串标准化+规则匹配
先对两个字段做标准化处理,再用规则匹配:
- 去除连续重复字母(比如把"Bannana"转成"Banana"、"Blaeze"转成"Blaze")
- 匹配门牌号+核心街道词
用正则替换处理重复字母的示例:
SELECT t1.city, t2.fruit FROM table1 t1 JOIN table2 t2 ON REGEXP_REPLACE(t1.street_1, '(.)\\1+', '\\1') = REGEXP_REPLACE(t2.street_2, '(.)\\1+', '\\1')
叠加门牌号精确匹配,能进一步提升准确率。
3. 关键词分词匹配
把街道字符串拆成单个词,统计两个字符串中匹配的关键词数量,达到阈值就关联(比如3个词里匹配2个以上)。
PostgreSQL示例:
SELECT t1.city, t2.fruit FROM table1 t1 JOIN table2 t2 ON ( SELECT COUNT(*) FROM unnest(string_to_array(t1.street_1, ' ')) AS w1 JOIN unnest(string_to_array(t2.street_2, ' ')) AS w2 ON w1 = w2 OR SOUNDEX(w1) = SOUNDEX(w2) ) >= 2
MySQL可通过REGEXP_SUBSTR拆分字符串,逻辑类似。
4. 预建映射表(小数据集首选)
如果数据量不大,直接人工核对生成街道映射表,把表1和表2的对应街道一一关联,这种方式准确率100%。
映射表示例:
| street_1 | street_2 |
|---|---|
| 123 Banana St | 123 Bannana St |
| 69 Good Time Rd | 69 Good Tme Rd |
| 420 Blaze It Dr | 420 Blaeze It Dr |
| 888 Wonderful Line | 888 Wonderaful Line |
关联SQL:
SELECT t1.city, t2.fruit FROM table1 t1 JOIN street_mapping m ON t1.street_1 = m.street_1 JOIN table2 t2 ON m.street_2 = t2.street_2
内容的提问来源于stack exchange,提问作者Isaac A
相关产品推荐
相关产品推荐

