【问题标题】:What is the best way to compare a name field with a string value?将名称字段与字符串值进行比较的最佳方法是什么?
【发布时间】:2019-02-09 20:47:33
【问题描述】:

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

John Doe
Doe John
Doe, John

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

Doe, John

查询:

full_name ILIKE 'Doe, John%'

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

【问题讨论】:

  • full_name in ('John Doe', 'Doe John', 'Doe, John')

标签: sql string postgresql where-clause sql-like


【解决方案1】:

选项 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 列上的索引,并生成全表扫描。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      你也可以试试这个

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

      【讨论】:

        【解决方案4】:

        这个:

        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)
          )
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-03
          • 2017-05-07
          • 1970-01-01
          • 1970-01-01
          • 2012-08-13
          • 1970-01-01
          • 2012-03-15
          相关资源
          最近更新 更多