从全名中获取名字的逻辑和查询

时间:2018-08-29 16:53:13

标签: sql postgresql

我有一个具有全名字段的大型数据库。全名可以是任何格式,也可以包括标题。例如,以下所有条件都是可能的:

John Smith
Smith, John
Mr. John Smith
Dr. John Smith
Mrs. Jane Smith
Ms. Jane Smith
Jane Smith, Esq.
Jane Smith, MD

我想保留全名字段,但还要从单独的表(包含姓名,性别)中添加预测的名字字段。

我认为,正确的逻辑是通过LIKE将名字值+空格匹配到全名表。该空格使“ David Johnson”与“ John”不匹配。

我认为完成此操作的方法是在其中添加一个子查询的update语句。这是我到目前为止的内容:

UPDATE "employees" 
    SET "employees".FirstName = (SELECT  firstname 
                                 FROM genders 
                                 WHERE fullname LIKE '%"employees".FirstName %')

1 个答案:

答案 0 :(得分:3)

您真正想做的是使用Postgres的全文搜索功能。您可以创建一个停用词列表,其中包含要排除的标题(先生,女士等)。然后,设置搜索配置以使用停用词。

正确设置了搜索配置后,查询将类似于以下内容(这是SELECT的变体:更改为UPDATE很简单)

SELECT employees.full_name, genders.first_name 
FROM employees
    LEFT JOIN genders ON
        TO_TSVECTOR('english_titles', employees.full_name) 
            @@ TO_TSQUERY('english_titles', genders.first_name)

这将为您提供以下结果:

full_name           first_name          
"John Smith"        "John"
"Smith, John"       "John"
"Mr. John Smith"    "John"
"Dr. John Smith"    "John"
"Mrs. Jane Smith"   "Jane"
"Ms. Jane Smith"    "Jane"
"Jane Smith, Esq."  "Jane"
"Jane Smith, MD"    "Jane"
"David Johnson"     NULL

要使其正常工作,您需要执行以下步骤:

  1. 创建一个包含职位名称的停用词文件,并将其放在您的$SHAREDIR/tsearch_data Postgres目录中。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS
  2. 创建一个使用此停用词列表的字典(您可以将pg_catalog.simple用作模板字典)。参见https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY
  3. 为职位创建搜索配置。参见https://www.postgresql.org/docs/9.1/static/textsearch-configuration.html
  4. 更改搜索配置以使用您在第2步中创建的字典(请参见上面的链接)。

现在,尽管如此,您需要仔细考虑以下几点:

  • 您希望如何处理姓氏与Genders表中的名字匹配的人?例如,您有一个叫John Stuart的人,并且JohnStuart都在您的genders表中。您希望如何处理?
  • 您希望如何处理带有昵称或只有一个名字的人?我会强烈鼓励您阅读Falsehoods Programmers Believe About Names,以确保您没有做任何错误的假设。
  • 为什么您的表包含第一个名为genders的表?您是否希望按性别匹配人们的名字?如果是这样,那是一条走下去的危险之路-有些名字可以用于任何性别。