【问题标题】:MySQL: Select longest string that occurs in search stringMySQL:选择搜索字符串中出现的最长字符串
【发布时间】:2016-12-20 22:25:18
【问题描述】:

我有一张这样的桌子:

id    path
1     /
2     /city/
3     /city/europe/
4     /city/north america/
6     /city/europe/germany/berlin/
7     /city/europe/germany/
8     /city/north america/usa/
[...]

和这样的搜索字符串:

"/city/north america/usa/florida/miami/"


我需要选择搜索字符串中最长的路径,因此结果将是

id   path
8    /city/north america/usa/


表中任何路径的每个父级都存在。路径可以任意长。搜索字符串至少包含“/”。

我可以想到一些解决方案,例如在列上使用通配符、拆分搜索字符串以及使用 IN 或连接执行选择。

最好和最快的方法是什么?
可以以任何方式修改表格。


编辑: 迄今为止我提出的最快的解决方案:

SELECT * FROM table_name
WHERE path IN ('/','/city/','/city/north america/', '/city/north  america/usa/', '/city/north america/usa/florida/', '/city/north america/usa/florida/miami/')
ORDER by LENGTH(path) DESC LIMIT 1;

【问题讨论】:

    标签: mysql string select wildcard


    【解决方案1】:
    SELECT * 
    FROM table_name 
    WHERE path REGEXP '^/city((((/north america)?/usa)?/florida)?/miami)?\/?$'
    ORDER BY LENGTH(path) DESC
    LIMIT 1
    

    【讨论】:

    • 那行不通。它返回所有列(并将其限制为一个结果,在这种情况下是错误的)
    • 它可以工作,但它需要比这长约 1000 倍:SELECT * FROM table_name WHERE path IN ('/','/city/','/city/north america/', '/city/north america/usa/', '/city/north america/usa/florida/', '/city/north america/usa/florida/miami/') ORDER by LENGTH(path) DESC LIMIT 1 但是,我认为这不是最好的解决方案。
    【解决方案2】:

    或者,试试这个:

    select * FROM tbl WHERE path=
    ( select max(path) from tbl 
      where '/city/north america/usa/florida/miami/' like concat(path,'%')
    )
    

    (编辑) 那么也许这会更快:

    select * from tbl where instr('/city/north america/usa/florida/miami/',path)=1 
    order by path desc limit 1
    

    【讨论】:

    • 单独的子查询就足够了,但与 WHERE IN 选择相比却相当慢。
    • 第二个查询其实慢了一点。它必须将该功能应用于每一行。我相信我可以通过在数据中使用树结构来以某种方式利用 b-tree 索引来发挥我的优势。如有必要,我也可以使用嵌套集,但这会使模型管理起来有点复杂。
    • 您的表可能存在一些索引问题?我的 fiddle 有 84000 条记录需要大约 16 毫秒才能完成。
    • 事实证明,您的WHERE IN (...) 和我的版本需要相同的执行时间。
    • 对不起,我忘了说路径栏是唯一的。使用 50000 行进行测试,WHERE IN 查询耗时
    猜你喜欢
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    相关资源
    最近更新 更多