相似性搜索姓氏姓氏

时间:2018-04-22 21:01:32

标签: sql postgresql

我有一个name列,其中包含name surname(姓名空间姓氏),我希望根据

进行搜索
  • namesurname但我希望与人们意外插入surname name不同顺序的案例相匹配
  • 错误拼写names surnames 1-2个字符。

2 个答案:

答案 0 :(得分:2)

您应该阅读pg_trgm extension及其功能similarity()。以下几个例子。

示例数据:

create table my_table(id serial primary key, name text);
insert into my_table (name) values
('John Wilcock'),
('Henry Brown'),
('Jerry Newcombe');

create extension if not exists pg_trgm; -- install the extension

示例1:

select *, 
    similarity(name, 'john wilcock') as "john wilcock",
    similarity(name, 'wilcock john') as "wilcock john"
from my_table;

 id |      name      | john wilcock | wilcock john 
----+----------------+--------------+--------------
  1 | John Wilcock   |            1 |            1
  2 | Henry Brown    |            0 |            0
  3 | Jerry Newcombe |     0.037037 |     0.037037
(3 rows)

示例2:

select *, 
    similarity(name, 'henry brwn') as "henry brwn",
    similarity(name, 'brovn henry') as "brovn henry"
from my_table;

 id |      name      | henry brwn | brovn henry 
----+----------------+------------+-------------
  1 | John Wilcock   |          0 |           0
  2 | Henry Brown    |   0.642857 |         0.6
  3 | Jerry Newcombe |       0.04 |   0.0384615
(3 rows)

示例3:

select *
from my_table
where similarity(name, 'J Newcombe') >= 0.6;

 id |      name      
----+----------------
  3 | Jerry Newcombe
(1 row) 

答案 1 :(得分:0)

要对付名称的交换部分,您可以使用split_part()将名称分成两部分并比较它们,类似于以下内容:

SELECT *
       FROM person
       WHERE split_part(name, ' ', 1) IN ('<given_name_searched_for>'
                                          '<surname_searched_for>')
              OR split_part(name, ' ', 2) IN ('<given_name_searched_for>'
                                              '<surname_searched_for>');

或者看看另一个string functions and operators. - 使用正则表达式的分裂函数的变体,例如..

是否有像'John F. Kennedy'这样的名字,即有多个令牌?是否有多个连续空格的名称?请记住,如果有的话,必须通过进一步的手段解决这些问题。 (这样的事情会变得毛茸茸。如果可能,请考虑修改你的设计,并为姓氏使用单独的专栏。)

对于相似性部分:PostgreSQL提供了一些在这里可能有用的模块: