我们有一些人以姓氏名字进入姓氏,反之亦然。所以我试图提出一个SQL搜索来匹配交换列。例如,某人可能偶然输入了first_name = Smith, last_name = John
的记录。之后,另一个人可能会看到John Smith不在数据库中并输入新用户first_name = John, last_name = Smith
,而实际上它是同一个人。
我使用此查询来缩小搜索范围:
SELECT person_id, first_name, last_name
FROM people
WHERE first_name IN (
SELECT last_name FROM people
) AND last_name IN (
SELECT first_name FROM people
);
但如果我们有名叫约翰艾伦,艾伦史密斯和史密斯约翰的人,他们都会被归还,即使这些都不是真的重复。在这种情况下,它实际上足够好,我可以在我的特定数据集中看到重复项,但我想知道是否有更精确的方法来执行此操作。
答案 0 :(得分:1)
我会像这样自我加入:
SELECT p1.person_id, p1.first_name, p1.last_name
FROM people p1
join people p2 on p1.first_name = p2.last_name and p1.last_name = p2.first_name
要在名字上找到拼写错误,我建议:
SELECT p1.person_id, p1.first_name, p1.last_name
FROM people p1
join people p2 on soundex(p1.first_name) = soundex(p2.last_name) and
soundex(p1.last_name) = soundex(p2.first_name)
soundex是一个简洁的函数,它以一种两个听起来相同的单词得到相同散列的方式“散列”单词。这意味着Anne和Ann将拥有相同的soundex。所以如果你有一个安妮史密斯和一个史密斯安,上面的查询就会发现它们是匹配的。
答案 1 :(得分:0)
有趣。这是我在使用SQL和Excel的数据分析中所涉及的问题(注意:我很少在我的答案或评论中提及书籍)。
这个想法是总结数据以获得不匹配的可能性。因此,请查看名称作为名字和姓氏出现的次数,然后将这些名称组合起来。所以:
with names as (
select first_name as name, 1.0 as isf, 0.0 as isl
from people
union all
select last_name, 0, 1
from people
),
nl as (
select name, sum(isf) as numf, sum(isl) as numl,
avg(isf) as p_f, avg(isl) as p_l
from names
group by name
)
select p.*
from people p join
nl nlf
on p.first_name = nlf.name join
nl nll
on p.last_name = nll.name
order by (coalesce(nlf.p_l, 0) + coalesce(nll.p_f, 0));
这通过一系列名称不匹配的方式对记录进行排序 - 这是姓氏使用的名字和作为名字的姓氏的概率之和。