Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何找到完全匹配全部或部分输入的字符串_Mysql_Sql - Fatal编程技术网

Mysql 如何找到完全匹配全部或部分输入的字符串

Mysql 如何找到完全匹配全部或部分输入的字符串,mysql,sql,Mysql,Sql,我想写一个查询来搜索一个包含数百万条记录的表,查找一个值,该值完全,并且只从一开始就与搜索字符串或其子字符串最匹配。表现是最重要的 这就像是一个反面: SELECT * FROM table_name WHERE column_name LIKE '$input%' LIMIT 1 例如,我想在下表中搜索foobar。如果foobar不存在,则搜索fooba,直到最后一个字符f,并返回与之完全匹配的行 +------------------+ | column_name | +---

我想写一个查询来搜索一个包含数百万条记录的表,查找一个值,该值完全,并且只从一开始就与搜索字符串或其子字符串最匹配。表现是最重要的

这就像是一个反面:

SELECT * FROM table_name WHERE column_name LIKE '$input%' LIMIT 1
例如,我想在下表中搜索foobar。如果foobar不存在,则搜索fooba,直到最后一个字符f,并返回与之完全匹配的行

+------------------+
|    column_name   |
+------------------+
|    foobar        |
+------------------+
|    fooba         |
+------------------+
|    foob          |
+------------------+
|    foo           |
+------------------+
|    fo            |
+------------------+
|    foobarrrrr    |
+------------------+
|    foooooooooooo |
+------------------+
|    barfoo        |
+------------------+

我认为没有一种真正有效的方法,但是下面的方法可能会满足您的需要

首先,在
t(列名)
上创建索引

然后,将查询构造为:

select t.*
from ((select t.* from table_name where column_name = $input) union all
      (select t.* from table_name where column_name = left($input, 1)) union all
      (select t.* from table_name where column_name = left($input, 2)) union all
      (select t.* from table_name where column_name = left($input, 3)) union all
      (select t.* from table_name where column_name = left($input, 4)) union all
      . . .
     ) t
order by length(t.column_name) desc
limit 1;
注:

  • 这是在不同长度的
    $input
    前缀之间循环。您可以使用PHP完成此操作,并在第一次匹配时停止
  • 比较时应使用
    列\u name
    上的索引
  • 这仅限于精确的子字符串匹配(这就是我对问题的解释)

    • 我认为没有一种真正有效的方法,但下面的方法可能会满足您的需要

      首先,在
      t(列名)
      上创建索引

      然后,将查询构造为:

      select t.*
      from ((select t.* from table_name where column_name = $input) union all
            (select t.* from table_name where column_name = left($input, 1)) union all
            (select t.* from table_name where column_name = left($input, 2)) union all
            (select t.* from table_name where column_name = left($input, 3)) union all
            (select t.* from table_name where column_name = left($input, 4)) union all
            . . .
           ) t
      order by length(t.column_name) desc
      limit 1;
      
      注:

      • 这是在不同长度的
        $input
        前缀之间循环。您可以使用PHP完成此操作,并在第一次匹配时停止
      • 比较时应使用
        列\u name
        上的索引
      • 这仅限于精确的子字符串匹配(这就是我对问题的解释)

      您可以使用列值动态构建类似于的模式

      SELECT column_name
      FROM table_name
      WHERE 'foobar' LIKE CONCAT(column_name, '%')
      ORDER BY LENGTH(column_name) DESC
      LIMIT 1
      

      请注意,如果表很大,这将很慢,因为我认为它不能使用索引。如果这是一个问题,那么动态地构建查询会更好。

      您可以使用列值动态地构建类似于的模式

      SELECT column_name
      FROM table_name
      WHERE 'foobar' LIKE CONCAT(column_name, '%')
      ORDER BY LENGTH(column_name) DESC
      LIMIT 1
      


      请注意,如果表很大,这将很慢,因为我认为它不能使用索引。如果这是一个问题,动态构建查询会更好。

      如果我在这个表中搜索
      fred
      ,您会得到什么结果?以
      f
      开头的所有记录?(只是想理解一下你的逻辑,因为它有点不同寻常)。你会在你的例子中返回什么?是的,您将得到
      f
      作为结果更好的方法是使用基于全文的搜索-它有很多有趣的特性我研究了全文匹配,但找不到最合适的方法。如果我在这个表中搜索
      fred
      ,您会得到什么结果?以
      f
      开头的所有记录?(只是想了解一下你的逻辑,因为它有点与众不同)。你会在你的示例中返回什么?是的,你会得到
      f
      ,结果更好的方法是使用基于全文的搜索-它有很多有趣的特性我研究了全文匹配,但找不到最合适的方法。谢谢你的回答。我希望MySQL中能有一个方法。我想我会在php中使用
      do…while
      ,并在php中将字符串的长度减少1,然后在我的表中搜索该子字符串。这可能对长输入字符串的性能不好。您可以使用(@input,LEFT(@input,1),LEFT(@input,2),…)中的
      列名称来代替union(
      @Barmar。我关心的是,这是否总是在
      列\u name
      上使用索引。在这种情况下,MySQL可能会对索引非常挑剔。我认为MySQL通常非常擅长使用
      的索引,其中列名位于(列表)
      中。它容易出错的地方是()中的列名称所在的
      @Barmar。我认为在某种程度上,它更喜欢对列表进行排序,并对列表进行二进制搜索。列表可能必须比本例中的典型字符串长一点。谢谢您的回答。我希望MySQL中能有一个方法。我想我会在php中使用
      do…while
      ,并在php中将字符串的长度减少1,然后在我的表中搜索该子字符串。这可能对长输入字符串的性能不好。您可以使用(@input,LEFT(@input,1),LEFT(@input,2),…)中的
      列名称来代替union(
      @Barmar。我关心的是,这是否总是在
      列\u name
      上使用索引。在这种情况下,MySQL可能会对索引非常挑剔。我认为MySQL通常非常擅长使用
      的索引,其中列名位于(列表)
      中。它容易出错的地方是()中的列名称所在的
      @Barmar。我认为在某种程度上,它更喜欢对列表进行排序,并对列表进行二进制搜索。列表可能必须比本例中的典型字符串长一点。