MySQL - 如何查找具有最相似开头的单词

Pal*_*mer 5 mysql sql binary-search-tree

如何varchar在MySQL数据库中查找与指定单词最相似的词?

例如:

+-------------------+
|    word_column    | 
+-------------------+
| StackOferflow     |
| StackExchange     |
| MetaStackExchange |
|       ....        |
+-------------------+
Run Code Online (Sandbox Code Playgroud)

查询:call get_with_similar_begin('StackExch_bla_bla_bla');
输出:'StackExchange'

查询:call get_with_similar_begin('StackO_bla_bla_bla');
输出:'StackOferflow'


更新:

Select * from words where word_column like 'StackExch_bla_bla_bla'不会给出正确的结果,因为'StackExchange'与此过滤器不匹配.

附加信息:我已经BTREE-index开启word_column,我想尽可能使用它

shA*_*A.t 2

在 SQL Server 中,我们可以使用如下查询的 CTE 来实现您想要的:

declare @search nvarchar(255) = 'StackExch_bla_bla_bla';

-- A cte that contains `StackExch_bla_bla_bla` sub-strings: {`StackExch_bla_bla_bla`, `StackExch_bla_bla_bl`, ...,  `S`}
with cte(part, lvl) as (  
    select @search, 1
    union all 
    select substring(@search, 1, len(@search) - lvl), lvl + 1
    from cte
    where lvl < len(@search)
), t as (   -- Now below cte will find match level of each word_column
    select t.word_column, min(cte.lvl) matchLvl
    from yourTable t
    left join cte
      on t.word_column like cte.part+'%'
    group by t.word_column
)
select top(1) word_column
from t
where matchLvl is not null   -- remove non-matched rows
order by matchLvl;
Run Code Online (Sandbox Code Playgroud)

SQL Server Fiddle 演示

我需要更多时间在 MySQL 中找到一种方法,希望一些 MySQL 专家更快地回答;)。

我在 MySQL 中的最佳尝试是:

select tt.word_column
from (
  select t.word_column, min(lvl) matchLvl
  from yourTable t
  join (
    select 'StackExch_bla_bla_bla' part, 1 lvl
    union all select 'StackExch_bla_bla_bl', 2
    union all select 'StackExch_bla_bla_b', 3
    union all select 'StackExch_bla_bla_', 4
    union all select 'StackExch_bla_bla', 5
    union all select 'StackExch_bla_bl', 6
    union all select 'StackExch_bla_b', 7
    union all select 'StackExch_bla_', 8
    union all select 'StackExch_bla', 9
    union all select 'StackExch_bl', 10
    union all select 'StackExch_b', 11
    union all select 'StackExch_', 12
    union all select 'StackExch', 13
    union all select 'StackExc', 14
    union all select 'StackEx', 15
    union all select 'StackE', 16
    union all select 'Stack', 17
    union all select 'Stac', 18
    union all select 'Sta', 19
    union all select 'St', 20
    union all select 'S', 21
  ) p on t.word_column like concat(p.part, '%')
  group by t.word_column
  ) tt
order by matchLvl
limit 1;
Run Code Online (Sandbox Code Playgroud)

p我认为通过创建一个存储过程并使用临时表在子选择中存储值,您可以实现您想要的 -HTH ;)。

MySQL 小提琴演示