多年来,由于拼写错误,我们的数据表中添加了一些重复项。所以例如有人拼错了这个名字而不是O'leary写了Oleary。我们的系统认为它是一个完全不同的名称并且不会抱怨它,但是在大多数情况下它的同一个联系人输入两次(我没有建立这个系统)。
现在我想要做的是删除所有这些重复项,但我很难构建一个查询来显示它们。我确实尝试了UTL_MATCH并编写了一个查询,如果我提供名称,它将返回所有相似的名称。
select first_name from customers
where UTL_MATCH.edit_distance_similarity(first_name,'Oleary') > 60
order by first_name;
但是,我想构建一个查询,该查询将自动返回所有可能的重复项,而无需提供名称。有人能指出我正确的方向吗?
答案 0 :(得分:3)
您可以将其用于join
:
select c1.first_name, c2.first_name
from customers c1 join
customers c2
on UTL_MATCH.edit_distance(c1.first_name, c2.first_name) <= 3
order by c1.first_name;
注意:
edit_distance()
到edit_distance_similarity()
,因为我了解单位。答案 1 :(得分:3)
这样的东西在技术上会起作用。
select c1.first_name, c2.first_name
from customers c1
cross join customers c2
where utl_match.edit_distance_similarity( c1.first_name, c2.first_name ) > 60
order by c1.first_name
然而,除非你的customers
表恰好非常(非常)小,否则它会非常慢,因为你要将customers
表中的每一行与表中的每一行进行比较(和您的编辑距离相似性截止值非常低。为了加快速度,你可能不得不对你的数据做出假设,或做一些可以作为初步过滤器的事情。例如,如果您假设任何重复项都以相同的第一个字符开头,或者相同的前几个字符忽略标点符号,那么您可以大大减少需要匹配的对的数量,但有可能错过“Kustin”可能的事实是“贾斯汀”的拼写复制品,其中第一个字符是不同的。要求c2.customer_id > c1.customer_id
是另一个合理的过滤器,考虑假设您不需要每一对重复(即“Kustin / Justin”行可以存在而没有等效的“Justin / Kustin”行)。