3.3.4.7 Сравнение по шаблонам
В MySQL реализовано стандартное для SQL сравнение по шаблонам, а также
особый тип такого сравнения - он основан на использовании выражений,
подобных применяющимся в служебных программах Unix (таких, как vi, grep и
sed).
В SQL при сравнении по шаблону символ `_' обозначает любой одиночный
символ, а `%' - определенное количество символов (включая ноль символов).
В MySQL в SQL-шаблонах по умолчанию не учитывается регистр символов. При
работе с шаблонами SQL использование операторов =
или <>
не допускается,
вместо этого применяются операторы сравнения LIKE
или NOT LIKE
.
Найти все имена, начинающиеся с `b', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "b%";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
Найти все имена, заканчивающиеся на `fy', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "%fy";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Найти все имена, содержащие `w', можно следующим образом:
mysql> SELECT * FROM pet WHERE name LIKE "%w%";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Найти все имена, содержащие ровно пять символов, можно при помощи
шаблонного символа `_':
mysql> SELECT * FROM pet WHERE name LIKE "_____";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Во втором типе шаблонов, предусмотренных в MySQL, используются расширенные
регулярные выражения. При поиске совпадений на основе такого шаблона
шаблоном нужно пользоваться операторами REGEXP
и NOT REGEXP
(или их
синонимами - RLIKE
и NOT RLIKE
).
Ниже приведены некоторые характеристики расширенных регулярных выражений:
-
`.' обозначает любой символ.
-
Класс символов `[...]' обозначает любой из символов в скобках.
Например, `[abc]' обозначает `a', `b' или `c'. Набор символов можно
обозначить с помощью дефиса. `[a-z]' обозначает любую букву нижнего
регистра, а `[0-9]' - любую цифру.
-
`*' обозначает ноль или более экземпляров символа, стоящего перед ним.
Например, `x*' обозначает любое количество символов `x', `[0-9]*'
обозначает любое количество цифр, а `.*' - любое количество любых
символов.
-
Для шаблона выдается совпадение, если поисковый контекст обнаружен в
любой из частей значения, в котором производится поиск (для шаблонов
SQL совпадение выдается только в случае, если совпадает все значение).
-
``Закрепить'' шаблон так, чтобы проверять совпадения с началом или
концом значения можно с помощью символов `^' (начало) или `$' (конец),
которые располагаются в начале или в конце шаблона соответственно.
Чтобы продемонстрировать работу регулярных выражений, приведенные выше
запросы LIKE
здесь переписаны с использованием REGEXP
.
Найти все имена, начинающиеся с `b', можно при помощи символа `^',
привязывающего шаблон к началу имени:
mysql> SELECT * FROM pet WHERE name REGEXP "^b";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
В версиях MySQL до 3.23.4 REGEXP
учитывает регистр символов, и приведенный
запрос не возвратит никаких результатов. Для поиска символов `b' верхнего
или нижнего регистра воспользуйтесь следующим запросом:
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
Начиная с версии MySQL 3.23.4, заставить REGEXP
учитывать регистр символов
можно с помощью ключевого слова BINARY
. В этом запросе положительный
результат поиска будет получен только при обнаружении символа 'b' нижнего
регистра в начале имени:
mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
Найти все имена, заканчивающиеся на `fy', можно при помощи символа `$',
привязывающего шаблон к концу имени:
mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
Найти все имена, содержащие символ `w' любого регистра, можно так:
mysql> SELECT * FROM pet WHERE name REGEXP "w";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
Поскольку регулярное выражение выдает положительный результат при
совпадении шаблона с любым фрагментом значения, в приведенном выше примере
привязывать поиск к любому из концов имени для сравнения полного значения
с шаблоном, как это пришлось бы делать для шаблона SQL, не нужно.
Найти все имена, содержащие ровно пять символов, можно, если привязать
поиск к началу и концу имени с помощью символов `^' и `$' и поставить пять
символов `.' между ними:
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Предыдущий запрос можно записать и при помощи оператора `{n}'
(``повторить-n
-раз''):
mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+