2.14: SQL-шаблоны.
Главная Страница » Книги по PHP » MySQL уроки для начинающих с нуля » Сравнение по шаблону. SQL-шаблоны.
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 | собака | f | 1989-05-13 | NULL |
| Bowser | Diane | собака | m | 1998-08-31 | 1995-07-29 |
+----------+--------+---------+------+------------+------------+
Чтобы найти имена, заканчивающиеся на сочетание fy, введите:
mysql> SELECT * FROM pet WHERE name LIKE "%fy";
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Fluffy | Harold | кошка | f | 1993-02-04 | NULL |
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
+----------+--------+---------+------+------------+------------+
Чтобы найти имена, содержащие букву w, введите:
mysql> SELECT * FROM pet WHERE name LIKE "%w%"
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Claws | Gwen | кошка | m | 1994-03-17 | NULL |
| Bowser | Diane | собака | m | 1998-08-31 | 1995-07-29 |
| Whistler | Gwen | птичка | NULL | 1997-12-09 | NULL |
+----------+--------+---------+------+------------+------------+
Чтобы найти имена, состоящие из пяти символов, используйте набор символов _:
mysql> SELECT * FROM pet WHERE name LIKE "_____"
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Claws | Gwen | кошка | m | 1994-03-17 | NULL |
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
+----------+--------+---------+------+------------+------------+
Другой тип образца, поддерживаемый MySQL, это расширенные регулярные выражения. Когда вы проверяете соответствия для этого типа образца, используйте операторы REGEXP и NOT REGEXP (или RLIKE и NOT RLIKE, которые являются синонимами) вместо уже знакомых LIKE и NOT LIKE. Некоторые правила задания расширенных регулярных выражений:
- точка (.) соответствует любому одиночному символу;
- символьный класс представляет собой набор символов, который обрабатывается при сравнении как один символ. Символьный класс [...] соответствует любому символу внутри скобок. Например, [abc] соответствует а или b или с. Чтобы задать диапазон символов, используйте черточку. Например, [a-z] соответствует любому латинскому символу нижнего регистра, в то время как [0-9] определяет любую цифру;
- звездочка * соответствует нулю или большему количеству образцов, предшествующих ей. Например, х* соответствует любому числу символов х, [0-9]* соответствует любому количеству цифр, а.* соответствует любому количеству чего-нибудь;
- регулярные выражения чувствительны к регистру, но вы можете использовать такой символьный класс, чтобы он соответствовал обоим регистрам сразу. Например, [аА] соответствует символу а нижнего или верхнего регистра, a [a-zA-Z] соответствует любому латинскому символу;
- образец в MySQL считается соответствующим, если соответствие происходит где-нибудь в проверяемом значении. Классический SQL учитывает соответствие, только если оно удовлетворяет всему значению в целом;
- чтобы закреплять образец так, чтобы он соответствовал строго началу или концу проверяемого значения, используется символ циркумфлекса (^) в начале или доллара ($) в конце образца.
Чтобы проиллюстрировать, как выполняется работа регулярных выражений, показанных выше, запросы LIKE переделаны ниже так, чтобы использовать их с REGEXP.
Чтобы находить имена, начинающиеся на b, примените ^ для соответствия началу имени:
mysql> SELECT * FROM pet WHERE паше REGEXP "^b";
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
| Bowser | Diane | собака | m | 1998-08-31 | 1995-07-29 |
+----------+--------+---------+------+------------+------------+
До MySQL версии 3.23.4 REGEXP чувствителен к регистру, и предыдущий запрос не возвратит никаких строк. Чтобы соответствовать нижнему или верхнему регистру b, используйте взамен этот запрос:
mysql> SELECT * FROM pet WHERE паше REGEXP "^[bВ]";
В MySQL 3.23.4, чтобы вынудить сравнение REGEXP стать чувствительным к регистру, используют ключевое слово BINARY, чтобы сделать одну из строк двоичной (в этом случае MySQL начинает сравнивать строки с учетом регистра посимвольно). Этот запрос будет соответствовать только нижнему регистру буквы 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 | кошка | f | 1993-02-04 | NULL |
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
+----------+--------+---------+------+------------+------------+
Чтобы находить имена, содержащие w, неважно в каком регистре, используйте этот запрос:
mysql> SELECT * FROM pet WHERE name REGEXP "w";
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Claws | Gwen | кошка | m | 1994-03-17 | NULL |
| Bowser | Diane | собака | m | 1998-08-31 | 1995-07-29 |
| Whistler | Gwen | птичка | NULL | 1997-12-09 | NULL |
+----------+--------+---------+------+------------+------------+
Потому что регулярное выражение срабатывает, если соответствие происходит где-нибудь в значении, в предыдущем запросе необязательно размещать групповой символ с обеих сторон образца, чтобы соответствовать всему значению. Хотя именно так пришлось бы поступить в стандартном SQL.
Чтобы находить имена, содержащие точно пять символов, используйте ^ и $, чтобы соответствовать началу, концу имени и пяти образцам точки . между ними:
mysql> SELECT * FROM pet WHERE name REGEXP ".....$"
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Claws | Gwen | кошка | m | 1994-03-17 | NULL |
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
+----------+--------+---------+------+------------+------------+
Вы могли бы также переписать предыдущий запрос, используя еще одну хитрость. Если после образца символа для соответствия поставить число n в фигурных скобках, то образец будет повторен п раз:
mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Claws | Gwen | кошка | m | 1994-03-17 | NULL |
| Buffy | Harold | собака | f | 1989-05-13 | NULL |
+----------+--------+---------+------+------------+------------+