MySQL, как в ()? - PullRequest
       132

MySQL, как в ()?

239 голосов
/ 14 июля 2009

Мой текущий запрос выглядит так:

SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %'

Я немного осмотрелся и не могу найти ничего похожего на LIKE IN () - я предполагаю, что это работает так:

SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %')

Есть идеи? Неужели я просто думаю о проблеме неправильно - какая-то непонятная команда, которую я никогда не видел.

MySQL 5.0.77-community-log

Ответы [ 10 ]

412 голосов
/ 14 июля 2009

A REGEXP может быть более эффективным, но вам, безусловно, придется его сравнить, например,

SELECT * from fiberbox where field REGEXP '1740|1938|1940'; 
161 голосов
/ 26 января 2011

Ответ Пола Диксона отлично сработал для меня. Чтобы добавить к этому, вот что я заметил для тех, кто заинтересован в использовании REGEXP:

Чтобы выполнить несколько фильтров LIKE с подстановочными знаками:

 SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                           OR field LIKE '%1938 %'
                           OR field LIKE '%1940 %';  

Использовать альтернативу REGEXP:

 SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 ';

Значения в кавычках REGEXP и между | (ИЛИ) оператор рассматривается как символы подстановки. Как правило, для REGEXP требуются символы подстановки, такие как (. *) 1740 (. *), Чтобы работать как% 1740%.

Если вам нужен больший контроль над размещением подстановочного знака, используйте некоторые из этих вариантов:

Чтобы выполнить LIKE с контролируемым размещением подстановочных знаков:

SELECT * FROM fiberbox WHERE field LIKE '1740 %'
                          OR field LIKE '%1938 '
                          OR field LIKE '%1940 % test';  

Использование:

SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test';
  • Помещение ^ перед значением указывает начало строки.

  • Размещение $ после значения указывает на конец строки.

  • Размещение (. *) Ведет себя подобно символу%.

  • . указывает на любой отдельный символ, кроме разрывов строк. Размещение inside () с * (. *) добавляет повторяющийся шаблон, указывающий любое число символов до конца строки.

Существуют более эффективные способы сужения конкретных совпадений, но для этого требуется более тщательный анализ регулярных выражений. ПРИМЕЧАНИЕ. Не все шаблоны регулярных выражений работают в инструкциях MySQL. Вам нужно проверить свои шаблоны и посмотреть, что работает.

Наконец, чтобы выполнить несколько фильтров LIKE и NOT LIKE:

SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                          OR field LIKE '%1938 %'
                          OR field NOT LIKE '%1940 %'
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

Использовать альтернативу REGEXP:

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$'
                          OR field NOT REGEXP '1940 |^test ';

ИЛИ Смешанная альтернатива:

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 '
                          OR field NOT REGEXP '1940 |^test '
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

Обратите внимание, что я отделил набор NOT в отдельном фильтре WHERE. Я экспериментировал с использованием отрицательных шаблонов, прогнозных шаблонов и так далее. Однако эти выражения, похоже, не дали желаемых результатов. В первом примере выше я использую ^ 9999 $, чтобы указать точное совпадение. Это позволяет вам добавлять конкретные совпадения с подстановочными совпадениями в одном выражении. Однако вы также можете смешивать эти типы операторов, как вы можете видеть во втором приведенном примере.

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

Как всегда, используйте логику выше, так как она имеет смысл.

Если вы хотите узнать больше о регулярных выражениях, я рекомендую www.regular-expressions.info как хороший справочный сайт.

14 голосов
/ 14 июля 2009

Вы можете создать встроенное представление или временную таблицу, заполнить ее значениями и выдать следующее:

SELECT  *
FROM    fiberbox f
JOIN    (
        SELECT '%1740%' AS cond
        UNION ALL
        SELECT '%1938%' AS cond
        UNION ALL
        SELECT '%1940%' AS cond
        ) с
ON      f.fiberBox LIKE cond

Это, однако, может вернуть вам несколько строк для fiberbox, что-то вроде '1740, 1938', так что этот запрос может подойти вам лучше:

SELECT  *
FROM    fiberbox f
WHERE   EXISTS
        (
        SELECT  1
        FROM    (
                SELECT '%1740%' AS cond
                UNION ALL
                SELECT '%1938%' AS cond
                UNION ALL
                SELECT '%1940%' AS cond
                ) с
        WHERE   f.fiberbox LIKE cond
        )
11 голосов
/ 12 июля 2013

Regexp путь со списком значений

SELECT * FROM table WHERE field regexp concat_ws("|",
"111",
"222",
"333");
7 голосов
/ 14 июля 2009

Извините, в mysql нет операции, аналогичной LIKE IN.

Если вы хотите использовать оператор LIKE без объединения, вам придется сделать это следующим образом:

(field LIKE value OR field LIKE value OR field LIKE value)

Знаете, MySQL не оптимизирует этот запрос, к вашему сведению.

4 голосов
/ 14 мая 2014

Просто обратите внимание всем, кто пытается использовать REGEXP для использования функции "LIKE IN".

IN позволяет делать:

field IN (
'val1',
'val2',
'val3'
)

В REGEXP это не сработает

REGEXP '
val1$|
val2$|
val3$
'

Это должно быть в одной строке, как это:

REGEXP 'val1$|val2$|val3$'
3 голосов
/ 06 декабря 2012

Перевернутые операнды

'a,b,c' like '%'||field||'%'
2 голосов
/ 06 ноября 2014

Просто небольшой совет:

Я предпочитаю использовать вариант RLIKE (точно такая же команда, как REGEXP ), так как он больше похож на естественный язык и короче; ну, всего 1 символ.

Префикс "R" для Reg. Эксп., Конечно.

2 голосов
/ 27 декабря 2013

Это было бы правильно:

SELECT * FROM table WHERE field regexp concat_ws("|",(
"111",
"222",
"333"
));
0 голосов
/ 04 декабря 2015

Вы можете получить желаемый результат с помощью Регулярных выражений .

SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]';

Мы можем проверить вышеуказанный запрос, пожалуйста, нажмите SQL-скрипта

SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]';

Мы можем проверить указанный выше запрос, пожалуйста, нажмите SQL-скрипта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...