将名称字段与字符串值进行比较的最佳方法是什么?

What is the best way to compare a name field with a string value?

我有一个查询,将字符串值与数据库中的名称字段进行比较。 DB中name字段的结构不一致,可能是这些:

John Doe
Doe John
Doe, John

我的字符串值可以是任何结构,但现在是这样的:

Doe, John

查询:

full_name ILIKE 'Doe, John%'

这并不总是 return 记录。在任何结构中进行比较的最可靠查询是什么?

选项 1 - 正如 melpomene 评论的那样:IN 条件

full_name IN ('John Doe', 'Doe John', 'Doe, John')

如果您事先知道全名的所有可能变体,这是最有效的方法。使用列 full_name 上的索引,应该非常快。

选项 2:确保名字和姓氏都是字符串的一部分:

full_name LIKE '%John%' AND full_name LIKE '%Doe%'

这样效率确实低。在左侧使用带有通配符的 LIKE 基本上会破坏列 full_name 上的索引,并生成完整的 table 扫描。

这个:

replace(replace(trim(full_name), ' ', ', '), ',,', ',')

会将 full_name 转换为:

'John, Doe''Doe, John' 即使它不包含 ,。 这些:

left(pattern, strpos(pattern, ',') - 1)
trim(substring(pattern, strpos(pattern, ',') + 1))

提取模式字符串值中 , 左右的内容。 所以你可以这样做:

replace(replace(trim(full_name), ' ', ', '), ',,', ',') in ( 
  pattern,
  concat(
    trim(substring(pattern, strpos(pattern, ',') + 1)),
    ', ',
    left(pattern, strpos(pattern, ',') - 1)
  )
)

您可以将其拆分为名称,然后使用 like 进行比较。例如:

where (select bool_and('doe john' like '%' || name || '%')
        from unnest(string_to_array(v.str, ' ')) name
       )

bool_and() 要求所有组件匹配。

也就是说,您应该修复数据模型,以便将名字和姓氏存储在不同的列中。

你也可以试试这个

full_name like any (values ('%John%', '%Doe%'))