Как найти строку, которая полностью совпадает с итогом или частью ввода в MySQL - PullRequest
0 голосов
/ 17 сентября 2018

Я хотел бы написать запрос для поиска в таблице, содержащей миллионы записей, значения, которое полностью и наилучшим образом соответствует строке поиска или ее подстроке только с самого начала. Производительность имеет наибольшее значение.

Это как обратная сторона:

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

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Вы можете использовать значение столбца для динамического построения шаблона LIKE.

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

Обратите внимание, что это будет медленно, если таблица большая, так как я не думаю, что она может использовать индекс. Если это проблема, динамическое построение запроса будет лучше.

0 голосов
/ 17 сентября 2018

Я не думаю, что есть действительно эффективный метод, но следующее может сделать то, что вы хотите.

Сначала создайте индекс для t(column_name).

Затем создайтезапрос как:

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 и остановиться на первом совпадении.
  • Индекс на column_name должен использоваться для сравнений.
  • Это только для точных совпадений подстрок (как яинтерпретирую вопрос).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...