【问题标题】:Postgresql : Find the string with the closest substring matchPostgresql :查找具有最接近子字符串匹配的字符串
【发布时间】:2017-07-13 07:40:37
【问题描述】:

如果我有一个表测试,其值如下:

id | value
----------------
1  | ABC 1-2-3
2  | AB 1-2-3-4-5
3  | ABC 1
4  | ABC 1-2
5  | ABC

我要输入的字符串是ABC 1-2-3-4-5,那么最接近的子字符串匹配(如果我可以这么称呼的话)应该是ABC 1-2-3。第 2 行不应该匹配,因为它没有“ABC”。如果输入字符串比实际记录短,我只能搜索字符串,但如果它更长,则不能。例如

select * from test where value ilike 'ABC 1-2%';

但这也没有给我一个确切的记录,而只是那些以 ABC 1-2 开头的记录。如何构造正确的 sql 语句来解决这个问题?

【问题讨论】:

    标签: string postgresql pattern-matching


    【解决方案1】:

    你可能对pg_trgm extension感兴趣:

    create extension if not exists pg_trgm;
    

    您的数据的标准相似性如下:

    select *, similarity(value, 'ABC 1-2-3-4-5')
    from test
    order by 3 desc;
    
     id |    value     | similarity 
    ----+--------------+------------
      2 | AB 1-2-3-4-5 |        0.8
      1 | ABC 1-2-3    |   0.714286
      4 | ABC 1-2      |   0.571429
      3 | ABC 1        |   0.428571
      5 | ABC          |   0.285714
    (5 rows)
    

    但是,您始终可以在 WHERE 子句中添加其他条件:

    select *, similarity(value, 'ABC 1-2-3-4-5')
    from test
    where value ilike 'abc%'
    order by 3 desc;
    
     id |   value   | similarity 
    ----+-----------+------------
      1 | ABC 1-2-3 |   0.714286
      4 | ABC 1-2   |   0.571429
      3 | ABC 1     |   0.428571
      5 | ABC       |   0.285714
    (4 rows)    
    

    【讨论】:

    • 我赞成这个,因为有一个实际的相似性度量,我将来可能会使用它。
    【解决方案2】:

    反转比较:

    select * from test
    where 'ABC 1-2-3-4-5' ilike value || '%'
    order by length(value) desc
    

    最好的(即最长的)匹配将首先返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-29
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 2011-08-17
      • 2014-06-08
      相关资源
      最近更新 更多