将名称字段与字符串值进行比较的最佳方法是什么?
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%'))
我有一个查询,将字符串值与数据库中的名称字段进行比较。 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%'))