Глава 13. Функции и операторы
Выражения могут использоваться в запросах
SQL, таких как ORDER BY или HAVING в
SELECT , в предложении
WHERE запросов SELECT ,
DELETE или
UPDATE или в операторе
SET .
Выражения могут быть написаны, используя литеральные значения, значения
столбцов, NULL , встроенные функции, сохраненные функции,
определяемые пользователем функции и операторы. Эта глава описывает функции и
операторы, которые разрешены для того, чтобы написать выражения в MySQL.
Инструкции для того, чтобы написать сохраненные функции и определяемые
пользователем функции даны в разделах
21.2 и
26.4. См.
раздел 10.2.4 для правил,
описывающих, как сервер интерпретирует ссылки на различные виды функций.
Выражение, которое содержит NULL всегда производит
NULL , если иное не обозначено в документации для особой
функции или оператора.
По умолчанию, не должно быть никакого пробела между именем функции и
круглой скобкой после этого. Это помогает анализатору MySQL различить вызовы
функции и ссылки на таблицы или столбцы, у которых, оказывается, есть то же
самое имя, как у функции. Однако, пробелы вокруг
функциональных параметров разрешены.
Вы можете сказать серверу MySQL принимать пробелы после имен функций,
запуская его с опцией
--sql-mode=IGNORE_SPACE . См.
раздел 6.1.8.
Отдельные программы клиента могут просить это поведение при использовании
опции CLIENT_IGNORE_SPACE для
mysql_real_connect()
. В этом случае все имена функций становятся зарезервированными словами.
Ради краткости большинство примеров в этой главе выводит на экран вывод из
программы mysql
в сокращенной форме. Вместо того, чтобы показывать примеры в этом формате:
mysql> SELECT MOD(29,9);
+-----------+
| mod(29,9) |
+-----------+
| 2 |
+-----------+
1 rows in set (0.00 sec)
Этот формат используется:
mysql> SELECT MOD(29,9);
-> 2
13.1. Обзор функций и операторов
Таблица 13.1. Функции и операторы
Имя | Описание |
ABS()
| Возвращает абсолютное значение |
ACOS()
| Возвращает арккосинус |
ADDDATE()
| Добавляет интервал времени к значению даты |
ADDTIME()
| Добавляет время |
AES_DECRYPT() | Дешифрует с использованием AES |
AES_ENCRYPT() | Шифрует с использованием AES |
AND ,
&& | Логический AND |
ANY_VALUE() | Подавить отклонение значения
ONLY_FULL_GROUP_BY |
ASCII()
| Возвращает числовое значение крайнего левого символа |
ASIN()
| Арксинус |
=
| Назначает значение (как часть
SET ) |
:=
| Назначает значение |
ASYMMETRIC_DECRYPT() |
Дешифрует зашифрованный текст, используя частный или открытый ключ |
ASYMMETRIC_DERIVE() |
Получить симметричный ключ из асимметричных ключей |
ASYMMETRIC_ENCRYPT() |
Шифрует открытый текст, используя частный или открытый ключ |
ASYMMETRIC_SIGN() |
Генерирует сигнатуру |
ASYMMETRIC_VERIFY() |
Проверяет соответствие сигнатуры |
ATAN()
| Арктангенс |
ATAN2() ,
ATAN() | Арктангенс двух параметров |
AVG()
| Среднее значение |
BENCHMARK()
| Неоднократно выполняет выражение |
BETWEEN ... AND ... | Проверяет, находится ли значение в
пределах диапазона значений |
BIN()
| Строка, содержащая двоичное представление числа |
BIN_TO_UUID() | Конвертирует двоичный UUID в строку
|
BINARY
| Преобразует обычную строку в двоичную |
BIT_AND()
| Битовое AND |
BIT_COUNT()
| Возвратить число битов, которые установлены |
BIT_LENGTH() | Длина параметра в битах |
BIT_OR()
| Битовое OR |
BIT_XOR()
| Битовое XOR |
&
| Битовое AND |
~ | Битовая инверсия |
|
| Битовое OR |
^
| Битовое XOR |
CASE
| Оператор Case |
CAST()
| Приводит значение к определенному типу |
CEIL()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CEILING()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CHAR()
| Возвратить символ для каждого целого числа |
CHAR_LENGTH() | Число символов в параметре |
CHARACTER_LENGTH() | Синоним CHAR_LENGTH() |
CHARSET()
| Набор символов параметра |
COALESCE()
| Первый не-NULL параметр |
COERCIBILITY() | Сопоставление значения строкового параметра
|
COLLATION()
| Сопоставление значения строкового параметра |
COMPRESS()
| Возвращает результат как двоичную строку |
CONCAT()
| Конкатенация строк |
CONCAT_WS()
| Конкатенация строк с сепаратором |
CONNECTION_ID() | ID соединения (ID потока) |
CONV()
| Преобразует числа между системами счисления |
CONVERT()
| Возвращает значение в качестве определенного типа
|
CONVERT_TZ() | Преобразует временные зоны |
COS()
| Косинус |
COT()
| Котангенс |
COUNT()
| Число строк |
COUNT(DISTINCT) | Число различных значений |
CRC32()
| Значение циклического контроля по избыточности |
CREATE_ASYMMETRIC_PRIV_KEY() |
Создает приватный ключ |
CREATE_ASYMMETRIC_PUB_KEY() |
Создает публичный ключ |
CREATE_DH_PARAMETERS() |
Генерирует разделяемый DH |
CREATE_DIGEST() |
Генерирует дайджест строки |
CURDATE()
| Текущяя дата |
CURRENT_DATE() , CURRENT_DATE |
Синонимы для CURDATE() |
CURRENT_ROLE() | Текущяя активная роль |
CURRENT_TIME() , CURRENT_TIME |
Синонимы для CURTIME() |
CURRENT_TIMESTAMP() , CURRENT_TIMESTAMP |
Синонимы для NOW() |
CURRENT_USER() , CURRENT_USER |
Имя пользователя и имя хоста |
CURTIME()
| Текущее время |
DATABASE()
| Имя базы данных по умолчанию |
DATE()
| Извлекает часть даты из date или datetime |
DATE_ADD()
| Добавляет интервал к дате |
DATE_FORMAT() | Форматирует дату как надо |
DATE_SUB()
| Вычитает интервал из даты |
DATEDIFF()
| Вычитает две даты |
DAY()
| Синоним для DAYOFMONTH() |
DAYNAME()
| Название дня |
DAYOFMONTH() | День месяца (0-31) |
DAYOFWEEK()
| День недели (индекс) |
DAYOFYEAR()
| День года (1-366) |
DECODE()
| Декодирует строку из ENCODE() |
DEFAULT()
| Значение по умолчанию для столбца таблицы |
DEGREES()
| Конвертирует радианы в degrees |
DES_DECRYPT() | Дешифрует строку |
DES_ENCRYPT() | Шифрует строку |
DIV
| Целочисленное деление |
/
| Оператор деления |
ELT()
| Строка как номер в индексе |
ENCODE()
| Шифрует строку |
ENCRYPT()
| Шифрует строку |
=
| Оператор равенства |
<=>
| Оператор равенства, защищенный от NULL |
EXP()
| Возведение в степень |
EXPORT_SET() | Возвращает строку таким образом, что для
каждого установленного бита Вы получаете строку on, а для каждого
неустановленного бита строку off |
EXTRACT()
| Извлекает часть даты |
ExtractValue() | Извлекает значение из строки XML,
используя нотацию XPath |
FIELD()
| Индекс (позиция) первого параметра в последующих параметрах
|
FIND_IN_SET() | Номер позиции первого параметра в
пределах второго параметра |
FLOOR()
| Самое большое целочисленное значение, не больше, чем параметр
|
FORMAT()
| Число, отформатированное к конкретному
количеству десятичных разрядов |
FOUND_ROWS() | Для SELECT с предложением LIMIT
число строк, которые были бы возвращены, если бы там не было LIMIT |
FROM_BASE64() | Декодирует строку base-64 |
FROM_DAYS()
| Конвертирует число дней в дату |
FROM_UNIXTIME() | Форматирует Unix timestamp в дату |
GeometryCollection() |
Создает набор геометрии из конфигураций |
GET_FORMAT() | Дата, сформатированная в строку |
GET_LOCK()
| Получить названную блокировку |
>
| Оператор "больше чем" |
>= | Оператор "больше чем или равно" |
GREATEST()
| Самый большой параметр |
GROUP_CONCAT() | Конкатенация строк |
GTID_SUBSET() | Возвратит истину, если все GTID в
подмножестве установлены, иначе ложь |
GTID_SUBTRACT() | Возвратит все GTID в наборе, которые
не находятся в подмножестве. |
HEX()
| Возвратит шестнадцатеричное представление десятичного
числа или строки |
HOUR()
| Извлекает час |
IF()
| Конструкция If/else |
IFNULL()
| Конструкция Null If/else |
IN()
| Находится ли значение в пределах ряда значений |
INET_ATON()
| Числовое значение IP-адреса |
INET_NTOA()
| IP-адрес из числового значения |
INET6_ATON() | Числовое значение IPv6-адреса |
INET6_NTOA() | IPv6-адрес из числового значения |
INSERT()
| Вставить подстроку в указанной позиции |
INSTR()
| Индекс первого возникновения подстроки |
INTERVAL()
| Индекс параметра, который меньше, чем первый параметр
|
IS |
Проверка аргумента на двоичность |
IS_FREE_LOCK() | Свободна ли названная блокировка |
IS_IPV4()
| Является ли параметр адресом IPv4 |
IS_IPV4_COMPAT() | Является ли параметр
IPv4-совместимым адресом |
IS_IPV4_MAPPED() | Является ли параметр
IPv4-отображенным адресом |
IS_IPV6()
| Является ли параметр адресом IPv6 |
IS NOT
| Проверка аргумента на двоичность |
IS NOT NULL | Проверка NOT NULL |
IS NULL
| Проверка на NULL |
IS_USED_LOCK() | Используется ли названная блокировка,
возвратит идентификатор соединения, если да |
IS_UUID()
| Является ли параметр допустимым UUID |
ISNULL()
| Является ли параметр NULL |
JSON_ARRAY() | Создает массив JSON |
JSON_ARRAY_APPEND() |
Добавляет данные в документ JSON |
JSON_ARRAY_INSERT() | Вставляет в массив JSON |
JSON_ARRAYAGG() | Возвратит набор результатов как
единственный массив JSON |
->
| Возвращаемое значение столбца JSON после оценки пути,
эквивалент JSON_EXTRACT(). |
JSON_CONTAINS() | Содержит ли документ JSON указанный объект
|
JSON_CONTAINS_PATH() | Содержит ли документ JSON
какие-либо данные в пути |
JSON_DEPTH() | Максимальная глубина документа JSON |
JSON_EXTRACT() | Данные из документа JSON |
->> | Возвращаемое значение столбца JSON после оценки
пути и закрытия кавычки результат, эквивалент JSON_UNQUOTE(JSON_EXTRACT())
|
JSON_INSERT() | Вставляет данные в документ JSON |
JSON_KEYS()
| Массив ключей из документа JSON |
JSON_LENGTH() | Число элементов в документе |
JSON_MERGE() | Объединение документов JSON |
JSON_OBJECT() | Создать объект JSON |
JSON_OBJECTAGG() | Возвратит набор результатов как
единственный объект JSON |
JSON_QUOTE() | Цитировать документ JSON |
JSON_REMOVE() | Удалить данные из документа JSON |
JSON_REPLACE() | Заменить значения в документе JSON |
JSON_SEARCH() | Путь в пределах документа JSON |
JSON_SET()
| Вставить данные в документ JSON |
JSON_TYPE()
| Тип значения JSON |
JSON_UNQUOTE() | Отменить цитирование значения JSON |
JSON_VALID() | Допустимо ли значение JSON |
LAST_DAY
| Последний день месяца для параметра |
LAST_INSERT_ID() | Значение столбца AUTOINCREMENT
для последнего INSERT |
LCASE()
| Синоним для LOWER() |
LEAST()
| Самый маленький параметр |
LEFT()
| Крайнее левое число символов как определено |
<<
| Сдвиг влево |
LENGTH()
| Возвратит длину строки в байтах |
<
| Оператор "меньше чем" |
<= | Оператор "меньше чем или равно" |
LIKE
| Простое соответствие образцу |
LineString() | Создает LineString из значений Point |
LN()
| Натуральный логарифм |
LOAD_FILE()
| Загрузить названный файл |
LOCALTIME()
, LOCALTIME | Синоним для NOW() |
LOCALTIMESTAMP , LOCALTIMESTAMP() |
Синоним для NOW() |
LOCATE()
| Возвратит позицию первого вхождения подстроки |
LOG()
| Натуральный логарифм первого параметра |
LOG10()
| Десятичный логарифм |
LOG2()
| Двоичный логарифм |
LOWER()
| Возвратит параметр в нижнем регистре |
LPAD()
| Возвратит строковый параметр, дополненный слева указанной строкой
|
LTRIM()
| Удалить ведущие пробелы |
MAKE_SET()
| Вернет ряд отделенных запятыми строк, у которых есть
соответствующий бит в наборе битов |
MAKEDATE()
| Создает дату из года и дня года |
MAKETIME()
| Создает время из часа, минуты и секунды |
MASTER_POS_WAIT() | Блокировка, пока ведомое устройство
считает и применит все обновления до указанной позиции |
MATCH
| Полнотекстовый поиск |
MAX()
| Максимальное значение |
MBRContains() | Содержит ли MBR одной геометрии MBR другой
|
MBRCoveredBy() | Покрыт ли один MBR другим |
MBRCovers()
| Покрывает ли один MBR другого |
MBRDisjoint() | Являются ли MBR двух конфигураций несвязными
|
MBREquals()
| Равны ли MBR двух конфигураций |
MBRIntersects() | Пересекаются ли MBR двух конфигураций
|
MBROverlaps() | Есть ли перекрытие у двух MBR |
MBRTouches() | Есть ли касание у двух MBR |
MBRWithin()
| Находится ли MBR одной геометрии в пределах MBR другой
|
MD5()
| Вычисляет хэш MD5 |
MICROSECOND() | Возвратит микросекунды из параметра |
MID()
| Возвратит подстроку, начиная с указанной позиции |
MIN()
| Минимальное значение |
-
| Оператор "-" |
MINUTE()
| Минута из параметра |
MOD()
| Остаток |
% ,
MOD | Модуль |
MONTH()
| Месяц из значения даты |
MONTHNAME()
| Имя месяца |
MultiLineString() | Собирает MultiLineString из LineString
|
MultiPoint() | Собирает MultiPoint из Point |
MultiPolygon() | Собирает MultiPolygon из Polygon |
NAME_CONST() | Присваивает имя столбцу |
NOT ,
! | Отрицает значение |
NOT
BETWEEN ... AND ... | Проверяет, не находится ли значение в
пределах диапазона значений |
!= ,
<> | Оператор "не равно" |
NOT IN()
| Проверяет, не находится ли значение в пределах ряда значений
|
NOT LIKE
| Отрицание простого соответствия образца |
NOT REGEXP
| Отрицание REGEXP |
NOW()
| Возвратит текущую дату и время |
NULLIF()
| Вернет NULL, если expr1 = expr2 |
OCT()
| Возвратит строку, содержащую октальное представление числа
|
OCTET_LENGTH() | Синоним для LENGTH() |
|| ,
OR | Логический OR |
ORD()
| Символьный код для крайнего левого символа параметра |
PASSWORD()
| Вычислит и возвратит строку пароля |
PERIOD_ADD() | Добавляет период к году и месяцу |
PERIOD_DIFF() | Возвратит число месяцев между периодами
|
PI()
| Значение числа pi |
+ |
Оператор "+" |
Point()
| Собирает Point из координат |
Polygon()
| Собирает Polygon из LineString |
POSITION()
| Синоним для LOCATE() |
POW()
| Возводит в указанную степень |
POWER()
| Возводит в указанную степень |
PROCEDURE ANALYSE() | Анализирует результаты запроса
|
QUARTER()
| Квартал из значения date |
QUOTE()
| Экранирует параметр для использования в запросе SQL |
RADIANS()
| Конвертирует в радианы |
RAND()
| Возвратит случайное значение с плавающей запятой |
RANDOM_BYTES() | Возвратит случайный вектор байта |
REGEXP
| Соответствие образца, используя регулярные выражения |
RELEASE_ALL_LOCKS() |
Освобождает все текущие именованные блокировки |
RELEASE_LOCK() | Освобождает именованную блокировку |
REPEAT()
| Повторит строку конкретное количество раз |
REPLACE()
| Заменяет указанную строку |
REVERSE()
| Перевернуть строку |
RIGHT()
| Самый правый символ |
>>
| Сдвиг вправо |
RLIKE
| Синоним для REGEXP |
ROLES_GRAPHML() | Возвращает документ GraphML,
представляющий ролевые подграфы памяти |
ROUND()
| Округлит параметр |
ROW_COUNT()
| Сколько строк обновлено |
RPAD()
| Добавляет строку конкретное количество раз |
RTRIM()
| Удалит конечные пробелы |
SCHEMA()
| Синоним для DATABASE() |
SEC_TO_TIME() | Конвертирует секунды в формат 'HH:MM:SS'
|
SECOND()
| Возвратит секунды (0-59) |
SESSION_USER() | Синоним для USER() |
SHA1() ,
SHA() | SHA-1 160-bit хэш |
SHA2()
| Хэш SHA-2 |
SIGN()
| Знак аргумента |
SIN()
| Синус |
SLEEP()
| Сон в течение указанного числа секунд |
SOUNDEX()
| Строка soundex |
SOUNDS LIKE | Сравнивает звуки |
SPACE()
| Возвратит строку из конкретного количества пробелов |
SQRT()
| Квадратный корень параметра |
ST_Area()
| Вернет область Polygon или MultiPolygon |
ST_AsBinary() , ST_AsWKB() |
Переходит от внутренней геометрии к WKB |
ST_AsGeoJSON() | Генерирует объект GeoJSON |
ST_AsText()
, ST_AsWKT() | Переходит от внутренней
геометрии к WKT |
ST_Buffer()
| Возвратит геометрию точек в пределах данного
расстояния от геометрии |
ST_Buffer_Strategy() | Произведет опцию стратегии для
ST_Buffer() |
ST_Centroid() | Вернет центр как точку |
ST_Contains() | Содержит ли одна геометрия другую |
ST_ConvexHull() | Возвратит выпуклый корпус геометрии |
ST_Crosses() | Пересекает ли одна геометрия другую |
ST_Difference() | Возвратит различие в наборе
точек двух конфигураций |
ST_Dimension() | Измерение геометрии |
ST_Disjoint() | Является ли одна
геометрия несвязной с другой |
ST_Distance() | Расстояние одной геометрии от другой |
ST_Distance_Sphere() | Минимальное расстояние на земле
между двумя конфигурациями |
ST_EndPoint() | Конечный Point LineString |
ST_Envelope() | MBR геометрии |
ST_Equals()
| Равна ли одна геометрия другой |
ST_ExteriorRing() | Возвратит внешнее кольцо Polygon |
ST_GeoHash() | Произведит значение geohash |
ST_GeomCollFromText() , ST_GeometryCollectionFromText() ,
ST_GeomCollFromTxt() | Набор геометрии из WKT |
ST_GeomCollFromWKB() , ST_GeometryCollectionFromWKB()
| Набор геометрии из WKB |
ST_GeometryN() | Возвратит N-ую геометрию
из набора геометрий |
ST_GeometryType() | Возвратит название типа геометрии |
ST_GeomFromGeoJSON() | Произведет геометрию из объекта
GeoJSON |
ST_GeomFromText() , ST_GeometryFromText() |
Набор геометрии из WKT |
ST_GeomFromWKB() , ST_GeometryFromWKB() |
Набор геометрии из WKB |
ST_InteriorRingN() | Вернет N-ое внутреннее кольцо Polygon
|
ST_Intersection() |
Пересечение набора точек двух конфигураций |
ST_Intersects() | Пересекает ли одна геометрия другую
|
ST_IsClosed() | Закрыта ли геометрия и проста |
ST_IsEmpty() | Функция заполнителя |
ST_IsSimple() | Проста ли геометрия |
ST_IsValid() | Допустима ли геометрия |
ST_LatFromGeoHash() | Возвратит широту из значения geohash
|
ST_Length()
| Возвратит длину LineString |
ST_LineFromText() , ST_LineStringFromText() |
Собирает LineString из WKT |
ST_LineFromWKB() , ST_LineStringFromWKB() |
Собирает LineString из WKB |
ST_LongFromGeoHash() | Возвратит долготу из значения geohash
|
ST_MakeEnvelope() | Прямоугольник вокруг двух точек |
ST_MLineFromText() , ST_MultiLineStringFromText() |
Собирает MultiLineString из WKT |
ST_MLineFromWKB() , ST_MultiLineStringFromWKB() |
Собирает MultiLineString из WKB |
ST_MPointFromText() , ST_MultiPointFromText() |
Собирает MultiPoint из WKT |
ST_MPointFromWKB() , ST_MultiPointFromWKB() |
Собирает MultiPoint из WKB |
ST_MPolyFromText() , ST_MultiPolygonFromText() |
Собирает MultiPolygon из WKT |
ST_MPolyFromWKB() , ST_MultiPolygonFromWKB() |
Собирает MultiPolygon из WKB |
ST_NumGeometries() | Число конфигураций в наборе геометрии
|
ST_NumInteriorRing() , ST_NumInteriorRings() |
Число углов в Polygon |
ST_NumPoints() | Число точек в LineString |
ST_Overlaps() | Перекрывает ли одна геометрия другую |
ST_PointFromGeoHash() |
Конвертирует geohash в POINT |
ST_PointFromText() | Собирает Point из WKT |
ST_PointFromWKB() | Собирает Point из WKB |
ST_PointN()
| Возвратит N-ую точку LineString |
ST_PolyFromText() , ST_PolygonFromText() |
Собирает Polygon из WKT |
ST_PolyFromWKB() , ST_PolygonFromWKB() |
Собирает Polygon из WKB |
ST_Simplify() | Возвратит упрощенную геометрию |
ST_SRID()
| Возвратит пространственный ссылочный системный
ID для геометрии |
ST_StartPoint() | Стартовая Point LineString |
ST_SymDifference() | Возвратит набор точек
симметрического различия двух конфигураций |
ST_Touches() | Касается ли одна геометрия другой |
ST_Union()
| Возвратит набор общих точек двух конфигураций |
ST_Validate() | Возвратит утвержденную геометрию |
ST_Within()
| Является ли одна геометрия в пределах другой |
ST_X()
| Координата X Point |
ST_Y()
| Координата Y Point |
STD()
| Возвратит стандартное отклонение |
STDDEV()
| Возвратит стандартное отклонение |
STDDEV_POP() | Возвратит стандартное отклонение |
STDDEV_SAMP() | Возвратит типовое стандартное отклонение
|
STR_TO_DATE() | Конвертирует строку в дату |
STRCMP()
| Сравнивает две строки |
SUBDATE()
|
Синоним для DATE_SUB(), когда вызвана с тремя параметрами |
SUBSTR()
| Вернет подстроку как определено |
SUBSTRING()
| Вернет подстроку как определено |
SUBSTRING_INDEX() | Вернет подстроку из строки
перед конкретным количеством разделителей |
SUBTIME()
| Вычитает время |
SUM()
| Вернет сумму |
SYSDATE()
| Время выполнения функции |
SYSTEM_USER() | Синоним для USER() |
TAN()
| Тангенс |
TIME()
| Извлекает часть времени из выражения |
TIME_FORMAT() | Форматирует время |
TIME_TO_SEC() |
Возвратит параметр, преобразованный в секунды |
TIMEDIFF()
| Вычитает время |
*
| Умножение |
TIMESTAMP()
| С единственным параметром эта функция возвращает дату или
выражение datetime, с двумя параметрами, их сумму |
TIMESTAMPADD() | Добавляет интервал к datetime |
TIMESTAMPDIFF() | Вычитает интервал из datetime |
TO_BASE64()
| Конвертирует параметр в строку base-64 |
TO_DAYS()
| Возвратит параметр даты, преобразованный в дни |
TO_SECONDS() | Возвратит параметр даты или datetime,
преобразованный в секунды с года 0 |
TRIM()
| Удаляет начальные и конечные пробелы |
TRUNCATE()
| Урезает к конкретному количеству десятичных разрядов
|
UCASE()
| Синоним для UPPER() |
-
| Меняет знак аргумента |
UNCOMPRESS() | Распаковывает сжатую строку |
UNCOMPRESSED_LENGTH() | Возвратит длину строки перед сжатием
|
UNHEX()
| Строка с hex-представлением числа |
UNIX_TIMESTAMP() | Unix timestamp |
UpdateXML()
| Возвратит замененный фрагмент XML |
UPPER()
| Конвертирует в верхний регистр |
USER()
| Имя пользователя и имя хоста клиента |
UTC_DATE()
| Текущая дата в UTC |
UTC_TIME()
| Текущее время в UTC |
UTC_TIMESTAMP() | Текущие дата и время в UTC |
UUID()
| Universal Unique Identifier (UUID) |
UUID_SHORT() | Числовое значение UUID |
UUID_TO_BIN() | Конвертирует UUID в двоичную строку |
VALIDATE_PASSWORD_STRENGTH() |
Определяет силу пароля |
VALUES()
| Определяет значения, которые будут использоваться в INSERT
|
VAR_POP()
| Возвратит различие стандарта |
VAR_SAMP()
| Возвратит типовое различие |
VARIANCE()
| Возвратит стандартное отклонение |
VERSION()
| Строка версии сервера MySQL |
WAIT_FOR_EXECUTED_GTID_SET() | Ждать, пока данные GTID
не выполнятся на ведомом устройстве |
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() | Ждать, пока данные
GTID не выполнятся на ведомом устройстве |
WEEK()
| Номер недели |
WEEKDAY()
| Индекс дня недели |
WEEKOFYEAR() | Календарная неделя для даты (1-53) |
WEIGHT_STRING() | Возвратит строку веса для строки |
XOR
| Логический XOR |
YEAR()
| Год |
YEARWEEK()
| Год и неделя |
13.2. Преобразование типов в выражениях
Когда оператор используется с операндами различных типов, происходит
преобразование, чтобы сделать операнды совместимыми. Некоторые преобразования
происходят неявно. Например, MySQL автоматически преобразовывает числа в
строки по мере необходимости, и наоборот.
mysql> SELECT 1+'1';
-> 2
mysql> SELECT CONCAT(2,' test');
-> '2 test'
Также возможно преобразовать число в строку, явно используя функцию
CAST() .
Преобразование происходит неявно с функцией
CONCAT() , потому что это
ожидает строковые параметры.
mysql> SELECT 38.8, CAST(38.8 AS CHAR);
-> 38.8, '38.8'
mysql> SELECT 38.8, CONCAT(38.8);
-> 38.8, '38.8'
См. ниже в этом разделе информацию о наборе символов неявных
преобразований числа в строку и измененные правила, которые относятся к
CREATE TABLE ... SELECT .
Следующие правила описывают, как преобразование происходит
для операций сравнения:
Если один или оба параметра NULL , результат сравнения
NULL , за исключением NULL -безопасного оператора
<=> . Для
NULL <=> NULL результат true.
Никакое преобразование не нужно.
- Если оба параметра строки, они сравнены как строки.
- Если оба параметра целые числа, они сравнены как целые числа.
- Шестнадцатеричные значения обработаны как двоичные строки, если
не сравниваются с числом.
- Если один из параметров столбец
TIMESTAMP или
DATETIME , а другой параметр
константа, она преобразована в timestamp прежде, чем сравнение будет
выполнено. Это сделано, чтобы быть более ODBC-благоприятным. Отметьте, что
это не сделано для параметров в IN()
! Для надежности всегда используйте полный datetime, дату или
строки времени, делая сравнения. Например, чтобы достичь лучших результатов,
используя BETWEEN
с датой или временем, надо использовать
CAST() , чтобы
явно преобразовать значения в желаемый тип данных.
Подзапрос единственной строки из таблицы или таблиц не считают константой.
Например, если подзапрос возвращает целое число, чтобы сравнить с
DATETIME , сравнение сделано как
два целых числа. Целое число не преобразовано во временное значение. Сравнить
операнды как DATETIME можно,
используя CAST() , чтобы
явно преобразовать значение подзапроса в
DATETIME .
- Если один из параметров десятичное значение, сравнение зависит от другого
параметра. Параметры сравнены как десятичные значения, если другой параметр
десятичное или целочисленное значение, или как значения с плавающей запятой,
если другой параметр - значение с плавающей запятой.
- Во всех других случаях параметры сравнены как (реальные)
числа с плавающей запятой.
Сравнение значений JSON имеет место на двух уровнях. Первый уровень
сравнения основан на типах значений JSON. Если типы отличаются, результат
сравнения определен тем, у какого типа есть более высокий приоритет. Если два
значения имеют тот же самый тип JSON, второй уровень сравнения происходит,
используя определенные для типа правила. Для сравнения JSON с не-JSON
значение не-JSON преобразовано в JSON и значения сравниваются значения JSON.
Следующие примеры иллюстрируют преобразование строк к числам
для операций сравнения:
mysql> SELECT 1 > '6x';
-> 0
mysql> SELECT 7 > '6x';
-> 1
mysql> SELECT 0 > 'x6';
-> 0
mysql> SELECT 0 = 'x6';
-> 1
Для сравнений строкового столбца с числом MySQL не может использовать
индексирование на столбце, чтобы искать значение быстро. Если
str_col индексированный строковый столбец, индекс не
может использоваться, выполняя поиск в следующем запросе:
SELECT * FROM tbl_name WHERE str_col =1;
Причина этого состоит в том, что есть много различных строк, которые можно
преобразовать в значение 1 , например,
'1' , ' 1' или '1a' .
Сравнения, которые используют числа с плавающей запятой (или значения,
которые преобразованы в числа с плавающей запятой) приблизительны, потому что
такие числа неточны. Это может бы привести к результатам,
которые кажутся непоследовательными:
mysql> SELECT '18015376320243458' = 18015376320243458;
-> 1
mysql> SELECT '18015376320243459' = 18015376320243459;
-> 0
Такие результаты могут произойти, потому что значения преобразованы в
числа с плавающей запятой, которые имеют только 53 бита
точности и подвергаются округлению:
mysql> SELECT '18015376320243459'+0.0;
-> 1.8015376320243e+16
Кроме того, преобразование строки в число с плавающей запятой и из целого
числа в число с плавающей запятой не обязательно проходит тот же самый путь.
Целое число может быть преобразовано в число с плавающей запятой центральным
процессором, тогда как строка преобразована посимвольно, что вовлекает
умножение с плавающей запятой.
Показанные результаты изменятся на различных системах, и могут быть
затронуты факторами, такими как архитектура ЭВМ, версия компилятора или
уровень оптимизации. Один способ избежать таких проблем состоит в том, чтобы
использовать CAST()
так, чтобы значение не было преобразовано неявно:
mysql> SELECT CAST('18015376320243459' AS UNSIGNED) = 18015376320243459;
-> 1
Сервер включает dtoa , конверсионную библиотеку, которая
обеспечивает улучшенное преобразование строк или значений
DECIMAL в значения
FLOAT /
DOUBLE :
Поскольку преобразования, произведенные этой библиотекой, отличаются в
некоторых случаях от неdtoa , существует потенциал для
несовместимостей в приложениях, которые полагаются на предыдущие результаты.
Например, приложениям, которые зависят от определенного точного результата
предыдущих преобразований, возможно, понадобилась бы корректировка, чтобы
приспособить дополнительную точность.
Библиотека dtoa предоставляет преобразованиям следующие
свойства. D представляет значение
DECIMAL
или строковое представление, F представляет число с
плавающей запятой в двоичном формате (IEEE).
F -> D
преобразование сделано с самой лучшей точностью,
возвращая D как самую короткую строку, которая уступает
F когда чтение назад округляется к самому близкому
значению в родном двоичном формате как определено IEEE.
D -> F
преобразование сделано таким образом что F
самое близкое родное двоичное число к входной строке десятичного числа
D .
Эти свойства подразумевают, что F ->
D -> F преобразования
без потерь, если F -inf ,
+inf или NaN . Последние значения не поддержаны,
потому что стандарт SQL определяет их как недопустимые значения для
FLOAT или
DOUBLE .
Для D -> F ->
D преобразования, достаточное условие для работы без потерь
это то, что D использует 15 или меньше цифр точности,
-inf , +inf или NaN .
В некоторых случаях преобразование без потерь возможно, даже если
D имеет больше, чем 15 цифр точности, но это не всегда.
Неявное преобразование числового или временного значения, чтобы
представить в виде строки производит значение, у которого есть набор символов
и сопоставление, определенное системными переменными
character_set_connection и
collation_connection
. Эти переменные обычно устанавливаются
SET NAMES .
Это означает, что такое преобразование приводит к символьной строке
(CHAR ,
VARCHAR или
LONGTEXT ), кроме случая, в котором
установлен набор символов соединения binary . В этом случае
конверсионный результат двоичная строка
(BINARY ,
VARBINARY или
LONGBLOB ).
Для выражений целого числа предыдущие замечания об
оценке выражения применяются несколько по-другому для
назначения выражения: например, в запросе
CREATE TABLE t SELECT integer_expr ;
В этом случае у таблицы в столбце, следующем из выражения, есть тип
INT или
BIGINT , в зависимости от
длины выражения целого числа. Если максимальная длина выражения не
вписывается в INT , вместо
него будет использован BIGINT
. Длина взята из значения max_length метаданных набора
результатов SELECT (см.
раздел 25.8.5).
Это означает, что Вы можете вызвать
BIGINT вместо
INT
при помощи достаточно длинного выражения:
CREATE TABLE t SELECT 000000000000000000000;
13.3. Операторы
Таблица 13.2. Операторы
Имя | Описание |
AND ,
&& | Логический AND |
=
| Назначает значение (как часть
SET ) |
:=
| Назначает значение |
BETWEEN ...
AND ... | Проверяет, является ли значение в
пределах диапазона значений |
BINARY
| Преобразует строку в двоичную |
&
| Битовое AND |
~
| Битовая инверсия |
|
| Битовое OR |
^
| Битовое XOR |
CASE
| Оператор Case |
DIV
| Целочисленное деление |
/
| Деление |
=
| Равенство |
<=>
| NULL-безопасный оператор равенства |
>
| Больше чем |
>= | Больше чем или равно |
IS |
Проверка на boolean |
IS NOT
| Проверка на boolean |
IS NOT NULL | Проверка на NOT NULL |
IS NULL
| Проверка на NULL |
->
| Возвращаемое значение столбца JSON после оценки пути,
эквивалент JSON_EXTRACT() |
->> | Возвращаемое значение столбца JSON после оценки
пути и закрытия кавычки, аналог JSON_UNQUOTE(JSON_EXTRACT()). |
<<
| Сдвиг влево |
<
| Меньше чем |
<= | Меньше чем или равно |
LIKE
| Простое соответствие образца |
-
| Минус |
% ,
MOD | Модуль числа |
NOT ,
! | Отрицание |
NOT
BETWEEN ... AND ... | Проверяет, не является ли значение в
пределах диапазона значений |
!= ,
<> | Не равно |
NOT LIKE
| Отрицание простого соответствия образца |
NOT REGEXP
| Отрицание REGEXP |
|| ,
OR | Логический OR |
+ |
Сложение |
REGEXP
| Соответствие образца, используя регулярные выражения |
>>
| Сдвиг вправо |
RLIKE
| Синоним для REGEXP |
SOUNDS
LIKE | Сравнение звуков |
*
| Умножение |
-
| Смена знака параметра |
XOR
| Логический XOR |
13.3.1. Приоритет операторов
Приоритет операторов показан в следующем списке, от самого высокого
приоритета до самого низкого. У операторов, которые показаны вместе на
строке, тот же самый приоритет.
INTERVAL
BINARY, COLLATE
!
- (unary minus), ~ (unary bit inversion)
^
*, /, DIV, %, MOD
-, +
<<, >>
&
|
= (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
BETWEEN, CASE, WHEN, THEN, ELSE
NOT
AND, &&
XOR
OR, ||
= (assignment), :=
Приоритет = зависит от того, используется ли это в качестве
оператора сравнения (= )
или как оператор назначения (
= ). Когда использующийся в качестве оператора сравнения,
есть тот же самый приоритет, что и у
<=> ,
>= ,
> ,
<= ,
< ,
<> ,
!= ,
IS ,
LIKE ,
REGEXP и
IN .
Когда используется в качестве оператора назначения, у него есть тот же самый
приоритет, что и у :=
. Разделы 14.7.4.1 и
10.4 объясняют, как MySQL определяет,
какая интерпретация = должна применяться.
Для операторов, которые на том же самом уровне приоритета в пределах
выражения, оценка происходит слева направо, за исключением того, что
присвоение происходит справа налево.
Значение некоторых операторов зависит от режима SQL:
Приоритет операторов определяет порядок оценки выражения. Чтобы
переопределить этот порядок и группировать члены явно, используйте
круглые скобки. Например:
mysql> SELECT 1+2*3;
-> 7
mysql> SELECT (1+2)*3;
-> 9
13.3.2. Функции сравнения и операторы
Таблица 13.3. Операторы сравнения
Имя | Описание |
BETWEEN
... AND ... | Проверяет, является ли значение в
пределах диапазона значений |
COALESCE()
| Вернет первый аргумент не-NULL |
=
| Равенство |
<=>
| NULL-безопасное равенство |
>
| Больше чем |
>= | Больше чем или равно |
GREATEST()
| Самый большой параметр |
IN()
| Проверяет, является ли значение в пределах ряда значений |
INTERVAL()
| Индекс параметра, который меньше, чем первый параметр
|
IS |
Проверка на boolean |
IS NOT
| Проверка на boolean |
IS NOT
NULL | Проверка на NOT NULL |
IS NULL
| Проверка на NULL |
ISNULL()
| Является ли параметром NULL |
LEAST()
| Самый маленький параметр |
<
| Меньше чем |
<= | Меньше чем или равно |
LIKE
| Простое соответствие образца |
NOT
BETWEEN ... AND ... | Проверяет, не является ли значение в
пределах диапазона значений |
!= ,
<> | Не равно |
NOT IN()
| Проверяет, не является ли значение в пределах ряда значений
|
NOT LIKE
| Отрицание простого соответствия образца |
STRCMP()
| Сравнить две строки |
Операции сравнения приводят к значению 1
(TRUE ), 0 (FALSE ) или
NULL . Эти операции работают и на числах, и на строках. Строки
автоматически преобразованы в числа, а числа в строки по мере необходимости.
Следующие относительные операторы сравнения могут использоваться, чтобы
сравнить не только скалярные операнды, но и операнды строки:
= > < >= <= <> !=
Описания для тех операторов позже в этом разделе детализируют, как они
работают с операндами строки. Для дополнительных примеров сравнений строки в
контексте подзапросов строки, см. раздел
14.2.10.5.
Некоторые из функций в этом разделе возвращают значения кроме
1 (TRUE ), 0 (FALSE ) или
NULL . Например,
LEAST() и
GREATEST() .
Однако, значение, которое они возвращают, основано на операциях сравнения,
выполненных согласно правилам, описанным в
разделе 13.2.
Чтобы преобразовать значение в определенный тип в целях сравнения, Вы
можете использовать CAST() .
Строковые значения могут быть преобразованы в различное использование набора
символов с помощью CONVERT()
.
По умолчанию, строковые сравнения не являются чувствительными к регистру и
используют текущий набор символов. Значение по умолчанию
latin1 (cp1252 West European), которое также работает хорошо
на английском языке.
=
Равенство:
mysql> SELECT 1 = 0;
-> 0
mysql> SELECT '0' = 0;
-> 1
mysql> SELECT '0.0' = 0;
-> 1
mysql> SELECT '0.01' = 0;
-> 0
mysql> SELECT '.01' = 0.01;
-> 1
Для сравнений строки (a, b) = (x, y) эквивалентно:
(a = x) AND (b = y)
<=>
NULL -безопасное равенство. Этот оператор выполняет сравнение
равенства как = , но
возвращает 1 вместо NULL , если оба операнда
NULL и 0 вместо NULL , если один
операнд NULL .
Оператор <=>
эквивалентен стандартному SQL IS NOT DISTINCT FROM .
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
-> 1, NULL, NULL
Для сравнений строк (a, b) <=> (x, y) эквивалентно:
(a <=> x) AND (b <=> y)
<> ,
!=
Не равно:
mysql> SELECT '.01' <> '0.01';
-> 1
mysql> SELECT .01 <> '0.01';
-> 0
mysql> SELECT 'zapp' <> 'zappp';
-> 1
Для сравнений строк (a, b) <> (x, y) и
(a, b) != (x, y) эквивалентно:
(a <> x) OR (b <> y)
<=
Меньше или равно:
mysql> SELECT 0.1 <= 2;
-> 1
Для сравнений строк (a, b) <= (x, y) эквивалентно:
(a < x) OR ((a = x) AND (b <= y))
<
Меньше:
mysql> SELECT 2 < 2;
-> 0
Для сравнений строк (a, b) < (x, y) эквивалентно:
(a < x) OR ((a = x) AND (b < y))
>=
Больше или равно:
mysql> SELECT 2 >= 2;
-> 1
Для сравнений строк (a, b) >= (x, y) эквивалентно:
(a > x) OR ((a = x) AND (b >= y))
>
Больше:
mysql> SELECT 2 > 2;
-> 0
Для сравнений строк (a, b) > (x, y) эквивалентно:
(a > x) OR ((a = x) AND (b > y))
IS
boolean_value
Сравнивает значение с булевым значением, где
boolean_value может быть
TRUE , FALSE или UNKNOWN .
mysql> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
-> 1, 1, 1
IS NOT
boolean_value
Сравнивает значение с булевым значением, где
boolean_value может быть
TRUE , FALSE или UNKNOWN .
mysql> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
-> 1, 1, 0
IS NULL
Является ли значение NULL .
mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
-> 0, 0, 1
Чтобы работать хорошо с программами ODBC, MySQL поддерживает следующие
дополнительные функции, используя
IS NULL :
Если переменная
sql_auto_is_null
установлена в 1, тогда после запроса, который успешно вставляет
автоматически произведенный AUTO_INCREMENT , Вы можете найти
это значение, делая запрос следующей формы:
SELECT * FROM tbl_name WHERE auto_col IS NULL
Если запрос возвращает строку, значение возврата то же самое, как будто Вы
вызвали LAST_INSERT_ID()
. Если нет успешно вставленного значения AUTO_INCREMENT
, запрос SELECT
не возвращает строки.
Поведение получения AUTO_INCREMENT при использовании
IS NULL
может быть отключено, устанавливая
sql_auto_is_null = 0
.
Значение по умолчанию
sql_auto_is_null 0.
- Для столбцов
DATE и
DATETIME , которые объявлены как
NOT NULL , Вы можете найти специальную дату
'0000-00-00' при использовании запроса:
SELECT * FROM tbl_name WHERE date_column IS NULL
Это необходимо, чтобы заставить некоторые приложения ODBC работать, потому
что ODBC не поддерживает значение даты '0000-00-00' .
См. Obtaining Auto-Increment Values и описание для опции
FLAG_AUTO_IS_NULL на
Connector/ODBC Connection Parameters.
IS NOT NULL
Проверяет, не является ли значение NULL .
mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
-> 1, 1, 0
expr
BETWEEN min AND max
Если expr больше чем или равен
min и expr
меньше чем или равно max ,
BETWEEN возвращает
1 , иначе 0 . Это эквивалентно выражению
(min <= expr AND
expr <= max ) ,
если все параметры имеют тот же самый тип. Иначе имеет место преобразование
типов, согласно правилам, описанным в
разделе 13.2, но ко всем
этим трем параметрам.
mysql> SELECT 2 BETWEEN 1 AND 3, 2 BETWEEN 3 and 1;
-> 1, 0
mysql> SELECT 1 BETWEEN 2 AND 3;
-> 0
mysql> SELECT 'b' BETWEEN 'a' AND 'c';
-> 1
mysql> SELECT 2 BETWEEN 2 AND '3';
-> 1
mysql> SELECT 2 BETWEEN 2 AND 'x-3';
-> 0
Для лучших результатов, используя
BETWEEN
с датой или временем, надо использовать
CAST() , чтобы
явно преобразовать значения в желаемый тип данных. Если Вы сравниваете
DATETIME с двумя значениями
DATE , преобразуйте
DATE в
DATETIME .
Если Вы используете такую строку, как '2001-1-1' в сравнении с
DATE , преобразуйте строку к
DATE .
expr
NOT BETWEEN min AND max
Это то же самое, как NOT (expr BETWEEN
min AND max ) .
COALESCE(value
,...)
Возвращает первое не-NULL значение в списке, или
NULL , если нет не-NULL значений.
mysql> SELECT COALESCE(NULL,1);
-> 1
mysql> SELECT COALESCE(NULL,NULL,NULL);
-> NULL
GREATEST(value1
,value2 ,...)
С двумя или большим числом параметров, возвращает самый большой параметр.
Параметры сравнены, используя те же самые правила, что касаются
LEAST() .
mysql> SELECT GREATEST(2,0);
-> 2
mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
-> 767.0
mysql> SELECT GREATEST('B','A','C');
-> 'C'
GREATEST()
возвращает NULL , если какой-либо параметр
NULL .
expr
IN (value ,...)
Возвращает 1 , если expr
равно любому из значений в списке IN , иначе 0 .
Если все значения константы, они оценены согласно типу
expr и отсортированы. Поиск элемента тогда сделан,
используя двоичный поиск. Это означает, что IN
очень быстр, если список значений IN состоит полностью из
констант. Иначе имеет место преобразование типов, согласно правилам,
описанным в разделе 13.2, но
ко всем параметрам.
mysql> SELECT 2 IN (0,3,5,7);
-> 0
mysql> SELECT 'wefwf' IN ('wee','wefwf','weg');
-> 1
IN может использоваться, чтобы сравнить конструкторы строки:
mysql> SELECT (3,4) IN ((1,2), (3,4));
-> 1
mysql> SELECT (3,4) IN ((1,2), (3,5));
-> 0
Вы никогда не должны смешивать заключенные в кавычки значения со
значениями без кавычек, потому что правила сравнения для заключенных в
кавычки значений (таких как строки) отличаются. Смешивание типов может
поэтому привести к непоследовательным результатам. Например, не пишите
такое выражение IN :
SELECT val1 FROM tbl1 WHERE val1 IN (1,2,'a');
Вместо этого напишите так:
SELECT val1 FROM tbl1 WHERE val1 IN ('1','2','a');
Число значений в списке IN ограничено только значением
max_allowed_packet
.
Для выполнения стандарта SQL, IN вернет NULL
не только если выражение на левой стороне NULL , но также если
никакое соответствие не найдено в списке, и одно из
выражений в списке NULL .
Синтаксис IN() может также использоваться, чтобы написать
определенные типы подзапросов. См.
раздел 14.2.10.3.
expr
NOT IN (value ,...)
Аналог NOT (expr IN
(value ,...)) .
ISNULL(expr )
Если expr NULL ,
ISNULL() вернет
1 , иначе 0 .
mysql> SELECT ISNULL(1+1);
-> 0
mysql> SELECT ISNULL(1/0);
-> 1
ISNULL()
может использоваться вместо
= , чтобы
проверить, является ли значение NULL . Сравнение значения
с NULL , используя
= всегда вернет NULL .
Функция ISNULL()
совместно использует некоторые специальные поведения с оператором
IS NULL .
См. описание IS NULL .
INTERVAL(N ,
N1 ,N2 ,N3 ,
...)
Вернет 0 если N
< N1 , 1 если
N < N2
и так далее или -1 если N
NULL . Все параметры обработаны как целые числа.
Для этой функции требуется N1
< N2 < N3 <
... < Nn , чтобы работать правильно.
Это потому, что двоичный поиск используется (очень быстрый).
mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
-> 3
mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
-> 2
mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
-> 0
LEAST(value1 ,
value2 ,...)
С двумя или большим числом параметров возвращает самый маленький
параметр. Параметры сравнены, используя следующие правила:
mysql> SELECT LEAST(2,0);
-> 0
mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
-> 3.0
mysql> SELECT LEAST('B','A','C');
-> 'A'
Отметьте, что предыдущие конверсионные правила могут привести к странным
результатам в некоторых промежуточных случаях:
mysql> SELECT CAST(LEAST(3600, 9223372036854775808.0) AS SIGNED);
-> -9223372036854775808
Это происходит, потому что MySQL читает 9223372036854775808.0
в контексте целого числа. Представление целого числа недостаточно хорошо,
чтобы содержать такое значение, таким образом, это превращается в целое
число со знаком.
13.3.3. Логические операторы
Таблица 13.4. Логические операторы
В SQL все логические операторы оценивают как TRUE ,
FALSE или NULL (UNKNOWN ). В MySQL
они осуществлены как 1 (TRUE ), 0 (FALSE ) и
NULL . Большая часть из этого характерна для различных серверов
базы данных SQL, хотя некоторые серверы могут возвратить любое ненулевое
значение для TRUE .
MySQL оценивает любое отличное от нуля, не-NULL значение как
TRUE . Например, все следующие запросы
оцениваются как TRUE :
mysql> SELECT 10 IS TRUE;
-> 1
mysql> SELECT -10 IS TRUE;
-> 1
mysql> SELECT 'string' IS NOT NULL;
-> 1
NOT ,
!
Логический NOT. Оценивается как 1 , если операнд
0 , как 0 , если операнд отличен от нуля и
NOT NULL вернет NULL .
mysql> SELECT NOT 10;
-> 0
mysql> SELECT NOT 0;
-> 1
mysql> SELECT NOT NULL;
-> NULL
mysql> SELECT ! (1+1);
-> 0
mysql> SELECT ! 1+1;
-> 1
Последний пример производит 1 потому, что выражение оценивает
тем же самым путь, как (!1)+1 .
AND ,
&&
Логический AND. Оценивается как 1 , если все операнды являются
отличными от нуля и не NULL , как 0 , если один или
более операндов 0 , иначе NULL возвращен.
mysql> SELECT 1 AND 1;
-> 1
mysql> SELECT 1 AND 0;
-> 0
mysql> SELECT 1 AND NULL;
-> NULL
mysql> SELECT 0 AND NULL;
-> 0
mysql> SELECT NULL AND 0;
-> 0
OR ,
||
Логический OR. Когда оба операнда не-NULL , результат
1 , если какой-либо операнд является отличным от нуля, и
0 иначе. Если один операнд NULL ,
результат 1 , если другой операнд является отличным от нуля,
иначе NULL . Если оба операнда
NULL , результат NULL .
mysql> SELECT 1 OR 1;
-> 1
mysql> SELECT 1 OR 0;
-> 1
mysql> SELECT 0 OR 0;
-> 0
mysql> SELECT 0 OR NULL;
-> NULL
mysql> SELECT 1 OR NULL;
-> 1
XOR
Логический XOR. Возвращает NULL , если любой операнд
NULL . Для не-NULL операндов, оценивает как
1 , если нечетное число операндов является отличным от
нуля, иначе вернет 0 .
mysql> SELECT 1 XOR 1;
-> 0
mysql> SELECT 1 XOR 0;
-> 1
mysql> SELECT 1 XOR NULL;
-> NULL
mysql> SELECT 1 XOR 1 XOR 1;
-> 1
a XOR b математически равно
(a AND (NOT b)) OR ((NOT a) and b) .
13.3.4. Операторы присваивания
Таблица 13.5. Операторы присваивания
Имя | Описание |
=
| Назначает значение (как часть
SET ) |
:=
| Назначает значение |
:=
Оператор назначения. Заставляет пользовательскую переменную на левой
стороне оператора брать значение с его правой стороны. Значение на правой
стороне может быть литеральным значением, другой переменной, хранящей
значение, или любым легальным выражением, которое приводит к скалярному
значению, включая результат запроса (при условии, что это значение
скалярное). Вы можете выполнить многократные назначения в том же самом
операторе SET .
Вы можете выполнить многократные назначения в том же самом запросе.
В отличие от = ,
:= никогда не
интерпретируется как оператор сравнения. Это означает, что Вы можете
использовать := в
в любом допустимом запросе SQL (не только в
SET ),
чтобы назначить значение переменной.
mysql> SELECT @var1, @var2;
-> NULL, NULL
mysql> SELECT @var1 := 1, @var2;
-> 1, NULL
mysql> SELECT @var1, @var2;
-> 1, NULL
mysql> SELECT @var1, @var2 := @var1;
-> 1, 1
mysql> SELECT @var1, @var2;
-> 1, 1
mysql> SELECT @var1:=COUNT(*) FROM t1;
-> 4
mysql> SELECT @var1;
-> 4
Вы можете сделать присвоение значения, используя
:= в
других запросах, кроме SELECT ,
например, в UPDATE :
mysql> SELECT @var1;
-> 4
mysql> SELECT * FROM t1;
-> 1, 3, 5, 7
mysql> UPDATE t1 SET c1 = 2 WHERE c1 = @var1:= 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT @var1;
-> 1
mysql> SELECT * FROM t1;
-> 2, 3, 5, 7
В то же время возможно установить и считать значение той же самой
переменной в единственном запросе SQL, используя
:= , но это не
рекомендуется. Раздел 10.4
объясняет, почему Вы должны избегать делать это.
=
Этот оператор используется, чтобы выполнить присвоение значения в двух
случаях, описанных в следующих двух параграфах.
В пределах SET
= обработан как оператор назначения, который заставляет
пользовательскую переменную на левой стороне оператора брать значение с его
правой стороны. Другими словами, когда используется в
SET , =
обработан тождественно :=
. Значение на правой стороне может быть литералом, другой
переменной, хранящей значение, или любым выражением, которое приводит к
скалярному значению, включая результат запроса (при условии, что это значение
скалярное). Вы можете выполнить многократные назначения в том же самом
SET .
В предложении SET запроса
UPDATE =
также действует как оператор назначения. В этом случае это заставляет
столбец, названный на левой стороне оператора, предполагать, что значение,
данное на правой стороне, предоставило любому WHERE условия,
которые являются частью UPDATE .
Вы можете сделать многократные назначения в том же самом SET
запроса UPDATE .
В любом другом контексте = обработан как
оператор сравнения.
mysql> SELECT @var1, @var2;
-> NULL, NULL
mysql> SELECT @var1 := 1, @var2;
-> 1, NULL
mysql> SELECT @var1, @var2;
-> 1, NULL
mysql> SELECT @var1, @var2 := @var1;
-> 1, 1
mysql> SELECT @var1, @var2;
-> 1, 1
13.4. Функции управления потоком
Таблица 13.6. Операторы управления
потоком
CASE
value WHEN
[compare_value ] THEN
result [WHEN
[compare_value ] THEN
result ...] [ELSE
result ] END
CASE WHEN
[condition ] THEN
result [WHEN
[condition ] THEN
result ...] [ELSE
result ] END
Первая версия возвращает result , где
value =compare_value .
Вторая версия возвращает результат для первого условия, которое является
истиной. Если не было никакого значения результата соответствия, вернется
результат после ELSE или NULL ,
если нет ELSE .
mysql> SELECT CASE 1 WHEN 1 THEN 'one'
-> WHEN 2 THEN 'two' ELSE 'more' END;
-> 'one'
mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
-> 'true'
mysql> SELECT CASE BINARY 'B'
-> WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
-> NULL
Тип возвращения CASE
совместимый тип всех возвращаемых значений, но также зависит от контекста, в
котором это используется. Если используется в строковом контексте, результат
возвращен как строка. Если в числовом контексте, результат возвращен как
десятичное, реальное или целочисленное значение.
Синтаксис CASE
expression, показанный здесь, отличается немного от
SQL CASE
statement, описанного в разделе
14.6.5.1 для использования в сохраненных программах. Оператор
CASE не может иметь
ELSE NULL и это закончено END CASE вместо
END .
IF(expr1 ,
expr2 ,expr3 )
Если expr1 TRUE
(expr1 <>
0 и expr1
<> NULL ), то
IF() вернет
expr2 , иначе вернет expr3 .
IF() возвращает числовое или
строковое значение, в зависимости от контекста, в котором используется.
mysql> SELECT IF(1>2,2,3);
-> 3
mysql> SELECT IF(1<2,'yes','no');
-> 'yes'
mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
-> 'no'
Если только один из expr2 или
expr3 явно NULL , тип результата функции
IF() будет типом
выражения не-NULL .
Тип возврата по умолчанию IF()
(который может иметь значение, когда это сохранено во временную
таблицу), вычислен следующим образом.
Выражение | Возвращаемое
значение |
expr2 или
expr3 возвращает строку | Строка |
expr2 или expr3
возвращает значение с плавающей запятой |
Значение с плавающей запятой |
expr2 или expr3
возвращает целое число | integer |
Если expr2 и expr3 строки,
результат является чувствительным к регистру, если любая строка является
чувствительной к регистру.
Есть также команда IF ,
которая отличается от функции IF()
. См. раздел 14.6.5.2.
IFNULL(expr1 ,
expr2 )
Если expr1 не NULL ,
IFNULL() вернет
expr1 , иначе expr2 .
IFNULL()
возвращает числовое или строковое значение, в зависимости от контекста, в
котором оно используется.
mysql> SELECT IFNULL(1,0);
-> 1
mysql> SELECT IFNULL(NULL,10);
-> 10
mysql> SELECT IFNULL(1/0,10);
-> 10
mysql> SELECT IFNULL(1/0,'yes');
-> 'yes'
Значение результата по умолчанию
IFNULL(expr1 ,
expr2 ) более
общее из двух выражений в следующем порядке:
STRING , REAL
или INTEGER .
Считайте случай таблицы основанным на выражениях или где MySQL должен
внутренне сохранить значение, возвращенное
IFNULL()
во временной таблице:
mysql> CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
mysql> DESCRIBE tmp;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| test | varbinary(4) | NO | | | |
+-------+--------------+------+-----+---------+-------+
В этом примере тип столбца test
VARBINARY(4) .
NULLIF(expr1 ,
expr2 )
Вернет NULL , если
expr1 = expr2 true,
иначе вернет expr1 . Это то же самое, как
CASE WHEN
expr1 = expr2 THEN NULL ELSE
expr1 END .
mysql> SELECT NULLIF(1,1);
-> NULL
mysql> SELECT NULLIF(1,2);
-> 1
Отметьте, что MySQL оценивает expr1
дважды, если параметры не равны.
13.5. Строковые функции
Таблица 13.7. Строковые функции
Имя | Описание |
ASCII()
| Возвращает числовое значение крайнего левого символа
|
BIN()
| Строка, содержащая двоичное представление числа |
BIT_LENGTH() | Длина параметра в битах |
CHAR()
| Возвратить символ для каждого целого числа |
CHAR_LENGTH() | Число символов в параметре |
CHARACTER_LENGTH() | Синоним для CHAR_LENGTH() |
CONCAT()
| Конкатенация строк |
CONCAT_WS()
| Конкатенация строк с сепаратором |
ELT()
| Строка как номер в индексе |
EXPORT_SET() | Возвращает строку таким образом, что для
каждого установленного бита Вы получаете строку on, а для каждого
неустановленного бита строку off |
FIELD()
| Индекс (позиция) первого параметра в последующих параметрах
|
FIND_IN_SET() | Номер позиции первого параметра в
пределах второго параметра |
FORMAT()
| Число, отформатированное к конкретному
количеству десятичных разрядов |
FROM_BASE64() | Декодирует строку base-64 |
HEX()
| Возвратит шестнадцатеричное представление десятичного
числа или строки |
INSERT()
| Вставить подстроку в указанной позиции |
INSTR()
| Индекс первого возникновения подстроки |
LCASE()
| Синоним для LOWER() |
LEFT()
| Крайнее левое число символов как определено |
LENGTH()
| Возвратит длину строки в байтах |
LIKE
| Простое соответствие образцу |
LOAD_FILE()
| Загрузить названный файл |
LOCATE()
| Возвратит позицию первого вхождения подстроки |
LOWER()
| Возвратит параметр в нижнем регистре |
LPAD()
| Возвратит строковый параметр, дополненный слева указанной строкой
|
LTRIM()
| Удалить ведущие пробелы |
MAKE_SET()
| Вернет ряд отделенных запятыми строк, у которых есть
соответствующий бит в наборе битов |
MATCH
| Полнотекстовый поиск |
MID()
| Возвратит подстроку, начиная с указанной позиции |
NOT LIKE
| Отрицание простого соответствия образца |
NOT REGEXP
| Отрицание REGEXP |
OCT()
| Возвратит строку, содержащую октальное представление числа |
OCTET_LENGTH() | Синоним для LENGTH() |
ORD()
| Символьный код для крайнего левого символа параметра |
POSITION()
| Синоним для LOCATE() |
QUOTE()
| Экранирует параметр для использования в запросе SQL |
REGEXP
| Соответствие образца, используя регулярные выражения |
REPEAT()
| Повторит строку конкретное количество раз |
REPLACE()
| Заменяет указанную строку |
REVERSE()
| Перевернуть строку |
RIGHT()
| Самый правый символ |
RLIKE
| Синоним для REGEXP |
RPAD()
| Добавляет строку конкретное количество раз |
RTRIM()
| Удалит конечные пробелы |
SOUNDEX()
| Строка soundex |
SOUNDS
LIKE | Сравнивает звуки |
SPACE()
| Возвратит строку из конкретного количества пробелов |
STRCMP()
| Сравнивает две строки |
SUBSTR()
| Вернет подстроку как определено |
SUBSTRING()
| Вернет подстроку как определено |
SUBSTRING_INDEX() | Вернет подстроку из строки
перед конкретным количеством разделителей |
TO_BASE64()
| Конвертирует параметр в строку base-64 |
TRIM()
| Удаляет начальные и конечные пробелы |
UCASE()
| Синоним для UPPER() |
UNHEX()
| Строка с hex-представлением числа |
UPPER()
| Конвертирует в верхний регистр |
WEIGHT_STRING() | Возвратит строку веса для строки
|
Функции, возвращающие строки, вернут NULL , если длина
результата больше, чем значение системной переменной
max_allowed_packet
. См. раздел 6.1.1.
Для функций, которые воздействуют на строковые позиции, первая позиция 1.
Для функций, которые берут параметры длины, параметры нецелого числа
округлены к самому близкому целому числу.
ASCII(str )
Возвращает числовое значение крайнего левого символа строки str
. Возвращает 0 , если str
пустая строка. Возвращает NULL , если str
NULL . ASCII()
работает для 8-битовых символов.
mysql> SELECT ASCII('2');
-> 50
mysql> SELECT ASCII(2);
-> 50
mysql> SELECT ASCII('dx');
-> 100
BIN(N )
Возвращает строковое представление двоичного значения
N , где N число типа longlong
(BIGINT ).
Это эквивалентно CONV(N
, 10, 2) . Вернет NULL , если
N NULL .
mysql> SELECT BIN(12);
-> '1100'
BIT_LENGTH(str
)
Возвращает длину строки str в битах.
mysql> SELECT BIT_LENGTH('text');
-> 32
CHAR(N ,...
[USING charset_name ])
CHAR()
интерпретирует каждый параметр N как integer
и возвращает строку, состоящую из символов, данных кодовыми обозначениями тех
целых чисел. NULL пропущены.
mysql> SELECT CHAR(77,121,83,81,'76');
-> 'MySQL'
mysql> SELECT CHAR(77,77.3,'77.3');
-> 'MMM'
Параметры CHAR() ,
больше чем 255, преобразованы в многобайтные результаты. Например,
CHAR(256) аналог
CHAR(1,0) , а
CHAR(256*256) аналог
CHAR(1,0,0) :
mysql> SELECT HEX(CHAR(1,0)), HEX(CHAR(256));
+----------------+----------------+
| HEX(CHAR(1,0)) | HEX(CHAR(256)) |
+----------------+----------------+
| 0100 | 0100 |
+----------------+----------------+
mysql> SELECT HEX(CHAR(1,0,0)), HEX(CHAR(256*256));
+------------------+--------------------+
| HEX(CHAR(1,0,0)) | HEX(CHAR(256*256)) |
+------------------+--------------------+
| 010000 | 010000 |
+------------------+--------------------+
По умолчанию CHAR()
возвращает двоичную строку. Чтобы произвести строку в заданном наборе
символов, используйте дополнительное определение USING :
mysql> SELECT CHARSET(CHAR(X'65')), CHARSET(CHAR(X'65' USING utf8));
+----------------------+---------------------------------+
| CHARSET(CHAR(X'65')) | CHARSET(CHAR(X'65' USING utf8)) |
+----------------------+---------------------------------+
| binary | utf8 |
+----------------------+---------------------------------+
Если USING задан, а строка результата незаконна для данного
набора символов, выдается предупреждение. Кроме того, если строгий режим SQL
включен, результатом CHAR()
будет NULL .
CHAR_LENGTH(str
)
Возвращает длину строки str в символах.
Мультибайтный символ считается единственным символом. Это означает, что для
строки, содержащей пять 2-байтовых символов,
LENGTH() вернет
10 , а
CHAR_LENGTH() 5 .
CHARACTER_LENGTH(
str )
CHARACTER_LENGTH()
синоним для
CHAR_LENGTH() .
CONCAT(str1 ,
str2 ,...)
Возвращает строку, которая следует из связывания параметров. Может иметь
один или более параметров. Если все параметры недвоичные строки, результат
недвоичная строка. Если параметры включают какие-либо двоичные строки,
результат двоичная строка. Числовой параметр преобразован в его эквивалентную
недвоичную строковую форму.
CONCAT() вернет
NULL , если какой-либо параметр NULL .
mysql> SELECT CONCAT('My', 'S', 'QL');
-> 'MySQL'
mysql> SELECT CONCAT('My', NULL, 'QL');
-> NULL
mysql> SELECT CONCAT(14.3);
-> '14.3'
Для заключенных в кавычки строк связь может быть выполнена, помещая строки
рядом друг с другом:
mysql> SELECT 'My' 'S' 'QL';
-> 'MySQL'
CONCAT_WS(separator
,str1 ,str2 ,...)
CONCAT_WS()
специальная форма CONCAT()
. Первый параметр разделитель для остальной части параметров. Разделитель
добавлен между строками, которые будут связаны. Разделитель может быть
строкой. Если разделитель NULL , результат NULL .
mysql> SELECT CONCAT_WS(',','First name','Second name','Last Name');
-> 'First name,Second name,Last Name'
mysql> SELECT CONCAT_WS(',','First name',NULL,'Last Name');
-> 'First name,Last Name'
CONCAT_WS()
не пропускает пустые строки. Однако, это действительно пропускает любой
NULL после параметра разделителя.
ELT(N ,
str1 ,str2 ,
str3 ,...)
ELT() вернет
N -ый списка строк: str1 , если
N = 1 ,
str2 , если
N = 2 и т.д. NULL , если
N меньше 1 или больше, чем число
параметров. ELT()
дополнение FIELD() .
mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
-> 'ej'
mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
-> 'foo'
EXPORT_SET(bits
,on ,off [,
separator [,number_of_bits ]])
Возвращает строку, где для каждого установленного бита в значении
bits будет значение on , а для
каждого не установленного off .
Биты в bits исследованы справа налево (от младшего
разряда до старшего). Строки добавлены к результату слева направо и отделены
параметром separator (значение по умолчанию: символ
запятой , ). Числом исследуемых битов задано
number_of_bits , по умолчанию 64, если не определено.
number_of_bits тихо усечено до 64, если больше, чем 64.
Это обработано как целое число без знака, таким образом, значение
-1 является эффективно тем же самым, что и 64.
mysql> SELECT EXPORT_SET(5,'Y','N',',',4);
-> 'Y,N,Y,N'
mysql> SELECT EXPORT_SET(6,'1','0',',',10);
-> '0,1,1,0,0,0,0,0,0,0'
FIELD(str ,
str1 ,str2 ,str3
,...)
Возвращает индекс (позицию) str
в списке str1 , str2 ,
str3 , ... . 0 , если
str не найдена.
Если все параметры FIELD()
строки, все параметры сравнены как строки. Если все параметры числа, они
сравнены как числа. Иначе, параметры сравнены как double.
Если str NULL , вернет 0
потому, что NULL подводит сравнение равенства с любым значением.
FIELD() дополняет
ELT() .
mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 2
mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 0
FIND_IN_SET(str
,strlist )
Возвращает значение в диапазоне от 1 до N ,
если строка str находится в строковом списке
strlist из N подстрок.
Строковый список это строка, составленная из подстрок, отделенных
символом , . Если первый параметр постоянная строка, а вторым
является столбец типа SET , функция
FIND_IN_SET()
оптимизирована, чтобы использовать разрядную арифметику. Возвращает
0 , если str не в strlist
или strlist пустая строка. Возвращает
NULL , если любой параметр NULL . Эта функция не
работает должным образом, если первый параметр содержит запятую
(, ).
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
FORMAT(X ,
D [,locale ])
Форматирует число X как '#,###,###.##' ,
округляя к D десятичных разрядов и возвращая результат
как строку. Если D 0 , у результата нет
никакой десятичной запятой или дробной части.
Дополнительный третий параметр позволяет определить локаль, из которой
брать символы для десятичной запятой, разделителя тысяч и групп. Допустимые
значения такие же, как и для системной переменной
lc_time_names (см.
раздел 11.7). Если локаль не
определена, значение по умолчанию 'en_US' .
mysql> SELECT FORMAT(12332.123456, 4);
-> '12,332.1235'
mysql> SELECT FORMAT(12332.1,4);
-> '12,332.1000'
mysql> SELECT FORMAT(12332.2,0);
-> '12,332'
mysql> SELECT FORMAT(12332.2,2,'de_DE');
-> '12.332,20'
FROM_BASE64(str
)
Берет строку, закодированную base-64 (например, с помощью
TO_BASE64() )
и возвращает расшифрованный результат как двоичную строку. Результат
NULL , если параметр NULL или не допустимая строка
base-64. См. описание
TO_BASE64() .
mysql> SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
-> 'JWJj', 'abc'
HEX(str )
, HEX(N )
Для строкового параметра str ,
HEX() возвращает
шестнадцатеричное строковое представление str , где
каждый байт каждого символа в str преобразован в две
шестнадцатеричных цифры. Мультибайтные символы поэтому становятся больше, чем
двумя цифрами. Инверсия этой работы выполнена функцией
UNHEX() .
Для числового параметра N ,
HEX()
возвращает шестнадцатеричное строковое представление значения
N как число longlong
(BIGINT ). Это эквивалентно
CONV(N ,10,16)
. Инверсия этой работы выполнена
CONV(HEX(N ),
16,10) .
mysql> SELECT X'616263', HEX('abc'), UNHEX(HEX('abc'));
-> 'abc', 616263, 'abc'
mysql> SELECT HEX(255), CONV(HEX(255),16,10);
-> 'FF', 255
INSERT(str ,
pos ,len ,newstr
)
Возвращает строку str с подстрокой, начинающейся в
позиции pos и len символов
длиной замененных строкой newstr . Возвращает
оригинальную строку, если pos не в пределах длины
строки. Заменяет остаток строки с позиции pos , если
len не в пределах длины остальной части строки.
Возвращает NULL , если какой-либо параметр NULL .
mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
-> 'QuWhattic'
mysql> SELECT INSERT('Quadratic', -1, 4, 'What');
-> 'Quadratic'
mysql> SELECT INSERT('Quadratic', 3, 100, 'What');
-> 'QuWhat'
Нормально работает с мультибайтными символами.
INSTR(str ,
substr )
Возвращает позицию первого возникновения подстроки
substr в строке str . Это то же
самое, что и форма с двумя параметрами
LOCATE() ,
за исключением того, что порядок параметров полностью изменен.
mysql> SELECT INSTR('foobarbar', 'bar');
-> 4
mysql> SELECT INSTR('xbar', 'foobar');
-> 0
Нормально работает с мультибайтными символами и является чувствительной к
регистру, только если по крайней мере один параметр двоичная строка.
LCASE(str )
LCASE() синоним для
LOWER() .
LCASE() используемая в представлении переписана как
LOWER() при сохранении определения представления (Bug #12844279).
LEFT(str ,
len )
Возвращает крайние левые len символы строки
str или NULL , если
какой-либо параметр NULL .
mysql> SELECT LEFT('foobarbar', 5);
-> 'fooba'
Нормально работает с мультибайтными символами.
LENGTH(str )
Возвращает длину строки str в байтах.
Мультибайтный символ считается несколькими байтами. Это означает, что для
строки, содержащей пять 2-байтовых символов,
LENGTH() вернет
10 , а
CHAR_LENGTH()
5 .
mysql> SELECT LENGTH('text');
-> 4
Пространственная функция Length() OpenGIS называется
ST_Length() в MySQL.
LOAD_FILE(file_name
)
Читает файл и возвращает содержание файла как строку. Чтобы использовать
эту функцию, файл должен быть расположен на хосте сервера, Вы должны
определить полный путь к файлу и иметь привилегию
FILE . Файл должен быть
читаемым всеми и его размер меньше, чем
max_allowed_packet
байт. Если системная переменная
secure_file_priv
установлена в непустое имя каталога, файл, который будет загружен,
должен быть расположен в том каталоге.
Если файл не существует или не может быть считан, потому что одно из
предыдущих условий не удовлетворено, функция вернет NULL .
Системная переменная
character_set_filesystem управляет интерпретацией имен
файлов, которые даны как буквальные строки.
mysql> UPDATE t SET blob_col=LOAD_FILE('/tmp/picture') WHERE id=1;
LOCATE(substr
,str ) ,
LOCATE(substr
,str ,pos )
Первый синтаксис возвращает позицию первого возникновения подстроки
substr в str .
Второй синтаксис возвращает позицию первого возникновения подстроки
substr в str , начиная с позиции
pos . Вернет 0 , если
substr нет в str . Вернет
NULL , если какой-либо параметр NULL .
mysql> SELECT LOCATE('bar', 'foobarbar');
-> 4
mysql> SELECT LOCATE('xbar', 'foobar');
-> 0
mysql> SELECT LOCATE('bar', 'foobarbar', 5);
-> 7
Функция является чувствительной к регистру, только если по крайней мере
один параметр двоичная строка.
LOWER(str )
Возвращает строку str со всеми символами,
измененными на нижний регистр согласно текущему отображению наборов символов.
Значение по умолчанию latin1 (cp1252 West European).
mysql> SELECT LOWER('QUADRATICALLY');
-> 'quadratically'
LOWER() (и
UPPER() )
неэффективны, когда применяются к двоичным строкам
(BINARY ,
VARBINARY и
BLOB ). Чтобы выполнить
преобразование в нижний регистр для них, сначала преобразуйте
такую строку в недвоичную:
mysql> SET @str = BINARY 'New York';
mysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));
+-------------+-----------------------------------+
| LOWER(@str) | LOWER(CONVERT(@str USING latin1)) |
+-------------+-----------------------------------+
| New York | new york |
+-------------+-----------------------------------+
Для сопоставлений наборов символов Unicode
LOWER() и
UPPER()
работают согласно Unicode Collation Algorithm (UCA) в версии для имени
сопоставления, если оно задано, и UCA 4.0.0, если версия не указана.
Например, utf8mb4_0900_ai_ci и utf8_unicode_520_ci
работают согласно UCA 9.0.0 и 5.2.0, соответственно, тогда как
utf8_unicode_ci работает по UCA 4.0.0. См.
раздел 11.1.10.1.
LCASE() , используемая в пределах представлений,
переписана как LOWER() .
LPAD(str ,
len ,padstr )
Возвращает строку str , доплненную слева строкой
padstr до длины len символов.
Если str длинней, чем
len , возвращаемое значение сокращено до
len символов.
mysql> SELECT LPAD('hi',4,'??');
-> '??hi'
mysql> SELECT LPAD('hi',1,'??');
-> 'h'
LTRIM(str )
Возвращает строку str из которой
удалены лидирующие пробелы.
mysql> SELECT LTRIM(' barbar');
-> 'barbar'
-
MAKE_SET(bits
, str1 , str2 , ...)
Возвращает значение набора (строка, содержащая подстроки, отделенные
, ) состоящее из строк, у которых есть соответствующий бит в
bits . str1 соответствует биту 0,
str2 1 и т.д. Значения NULL в
str1 , str2 , ...
не добавлены к результату.
mysql> SELECT MAKE_SET(1,'a','b','c');
-> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
-> 'hello,world'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
-> 'hello'
mysql> SELECT MAKE_SET(0,'a','b','c');
-> ''
MID(str ,
pos ,len )
MID(str ,
pos ,len ) синоним для
SUBSTRING(str
,pos ,len ) .
OCT(N )
Возвращает строковое представление октального значения
N , где N число longlong
(BIGINT ).
Это эквивалентно CONV(
N ,10,8) . Вернет NULL , если
N NULL .
mysql> SELECT OCT(12);
-> '14'
OCTET_LENGTH(str
)
OCTET_LENGTH()
синоним для LENGTH() .
ORD(str )
Если крайний левый символ строки str мультибайтный,
возвращает код для этого символа, вычисленный из числовых значений его
составляющих байтов, используя эту формулу:
(1st byte code)
+ (2nd byte code * 256)
+ (3rd byte code * 2562) ...
Если крайний левый символ однобайтный,
ORD() возвращает то же
самое значение, как функция
ASCII() .
mysql> SELECT ORD('2');
-> 50
POSITION(substr
IN str )
POSITION(substr
IN str ) синоним для
LOCATE(substr
,str ) .
QUOTE(str )
Заключает строку в кавычки, чтобы привести к результату, который может
использоваться в качестве должным образом составленного значения данных в
запросе SQL. Строка заключается в одинарные кавычки, каждый экземпляр
обратного слэша (\ ), одинарной кавычки
(' ), ASCII NUL и Control+Z предваряются
наклонной чертой влево. Если параметр
NULL , возвращаемое значение слово NULL
без одинарных кавычек.
mysql> SELECT QUOTE('Don\'t!');
-> 'Don\'t!'
mysql> SELECT QUOTE(NULL);
-> NULL
Для сравнения, см. правила заключения в кавычки для буквальных строк и в
C API в разделах 10.1.1 и
25.8.7.56.
REPEAT(str ,
count )
Возвращает строку, состоящую из строки
str , повторенной
count раз. Если
count меньше 1, вернется пустая строка. Вернет
NULL , если str или
count NULL .
mysql> SELECT REPEAT('MySQL', 3);
-> 'MySQLMySQLMySQL'
REPLACE(str ,
from_str ,to_str )
Возвращает строку str , в которой все вхождения
from_str заменены строкой to_str .
REPLACE() выполняет
чувствительное к регистру соответствие, ища from_str .
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
REVERSE(str )
Возвращает строку str , у которой
порядок символов перевернут.
mysql> SELECT REVERSE('abc');
-> 'cba'
RIGHT(str ,
len )
Возвращает самые правые len символы строки
characters from the string str или NULL ,
если какой-либо параметр NULL .
mysql> SELECT RIGHT('foobarbar', 4);
-> 'rbar'
RPAD(str ,
len ,padstr )
Возвращает строку str , к которой справа добавлена
padstr до длины в len символов.
Если str длинней len ,
возвращаемое значение сокращено до len символов.
mysql> SELECT RPAD('hi',5,'?');
-> 'hi???'
mysql> SELECT RPAD('hi',1,'?');
-> 'h'
RTRIM(str )
Возвращает строку str
с удаленными символами конечного пробела.
mysql> SELECT RTRIM('barbar ');
-> 'barbar'
SOUNDEX(str )
Возвращает строку soundex из str .
У двух строк, которые кажутся почти теми же самыми, должны быть идентичные
строки soundex. Стандарт soundex строка имеет длину 4 байта, но функция
SOUNDEX()
возвращает произвольно длинную строку. Вы можете использовать
SUBSTRING()
на результате, чтобы получить стандартную soundex-строку. Все небуквенные
символы в str проигнорированы. Все международные
буквенные символы вне диапазона A-Z обработаны как гласные.
Используя SOUNDEX() ,
Вы должны знать о следующих ограничениях:
Эта функция, как в настоящее время осуществлено, предназначена,
чтобы работать хорошо со строками, которые только на английском языке.
Строки на других языках, возможно, не приводят к надежным результатам.
- Эта функция, как гарантируют, не предоставит последовательный результат
для строк, которые используют многобайтовые наборы
символов, включая
utf-8 .
Мы надеемся удалить эти ограничения в будущем выпуске. См. Bug #22638.
mysql> SELECT SOUNDEX('Hello');
-> 'H400'
mysql> SELECT SOUNDEX('Quadratically');
-> 'Q36324'
Эта функция осуществляет оригинальный алгоритм Soundex, а не более
популярную улучшенную версию (также описанный D. Knuth). Различие в том, что
оригинальная версия отказывается от первой гласной и дублирует вторую, тогда
как улучшенная пропускает дубликаты первой и второй гласной.
expr1
SOUNDS LIKE expr2
Аналог SOUNDEX(expr1
) = SOUNDEX(expr2 ) .
SPACE(N )
Возвращает строку, состоящую из N пробелов.
mysql> SELECT SPACE(6);
-> ' '
SUBSTR(str ,
pos ) ,
SUBSTR(str
FROM pos ) ,
SUBSTR(str ,
pos ,len ) ,
SUBSTR(str
FROM pos FOR len )
SUBSTR() синоним для
SUBSTRING() .
SUBSTRING(str
,pos ) ,
SUBSTRING(str
FROM pos ) ,
SUBSTRING(str
,pos ,len ) ,
SUBSTRING(str
FROM pos FOR len )
Формы без len возвращают подстроку из
str , начиная с позиции pos .
Формы с len возвращают подстроку длиной
len символов из str , начиная с
позиции pos . Формы, которые используют
FROM , это стандартный синтаксис SQL.
Также возможно использовать отрицательную величину для
pos . В этом случае подстрока начинается с
pos символа от конца строки, а не начала.
Отрицательная величина может использоваться для pos
в любой из форм этой функции.
Для всех форм SUBSTRING()
позицию первого символа в строке, из которой должна быть
извлечена подстрока, считают как 1 .
mysql> SELECT SUBSTRING('Quadratically',5);
-> 'ratically'
mysql> SELECT SUBSTRING('foobarbar' FROM 4);
-> 'barbar'
mysql> SELECT SUBSTRING('Quadratically',5,6);
-> 'ratica'
mysql> SELECT SUBSTRING('Sakila', -3);
-> 'ila'
mysql> SELECT SUBSTRING('Sakila', -5, 3);
-> 'aki'
mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
-> 'ki'
Если len меньше 1, результат пустая строка.
SUBSTRING_INDEX(
str ,delim ,count )
Возвращает подстроку из строки str до
count возникновения разделителя
delim . Если count
положительно, возвращено все слева от заключительного разделителя (счет слева
направо). Если count отрицательно, возвращено все
справа от заключительного разделителя (считая справа).
SUBSTRING_INDEX()
выполняет чувствительное к регистру соответствие, ища
delim .
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
TO_BASE64(str
)
Преобразовывает строковый параметр в base-64 и возвращает результат как
строку символов с набором символов соединения и сопоставлением. Если параметр
не строка, он преобразован в строку прежде, чем преобразование будет иметь
место. Результат NULL если параметр NULL .
Строки Base-64 могут быть расшифрованы, используя функцию
FROM_BASE64() .
mysql> SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
-> 'JWJj', 'abc'
Существуют различные схемы кодировки Base 64.
TO_BASE64() и
FROM_BASE64()
используют следующие правила:
TRIM([{BOTH | LEADING | TRAILING}
[remstr ] FROM]
str ) ,
TRIM([remstr
FROM] str )
Возвращает строку str со всеми удаленными
префиксами или суффиксами remstr .
Если ни один из спецификаторов BOTH ,
LEADING или TRAILING не задан, предполагается
BOTH . remstr
является дополнительной и, если не определена, будут удалены пробелы.
mysql> SELECT TRIM(' bar ');
-> 'bar'
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx'
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar'
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
UCASE(str )
UCASE() синоним для
UPPER() .
UCASE() , используемая в пределах представлений переписана как
UPPER() .
UNHEX(str )
Для строкового параметра str
UNHEX(str )
интерпретирует каждую пару символов в параметре как
шестнадцатеричное число и преобразовывает это в байт, представленный числом.
Возвращаемое значение двоичная строка.
mysql> SELECT UNHEX('4D7953514C');
-> 'MySQL'
mysql> SELECT X'4D7953514C';
-> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
-> 'string'
mysql> SELECT HEX(UNHEX('1267'));
-> '1267'
Символы в строке параметра должны быть шестнадцатеричными цифрами:
'0' .. '9' , 'A' .. 'F' ,
'a' .. 'f' . Если параметр содержит какие-либо
нешестнадцатеричные цифры, результат NULL :
mysql> SELECT UNHEX('GG');
+-------------+
| UNHEX('GG') |
+-------------+
| NULL |
+-------------+
Результат NULL может произойти, если параметр
UNHEX() столбец
BINARY , потому что
значения дополнены байтами 0x00 когда сохранены, но эти байты при извлечении
не удаляются. Например, '41' сохранена в столбце
CHAR(3) как '41 ' и получена как '41'
(без хвостового пробела, таким образом
UNHEX() для значения столбца вернет 'A' .
При сохранении '41' в столбец
BINARY(3) сохранится и вернется '41\0'
(0x00 в конце останется). '\0' не
шестнадцатеричная цифра, таким образом,
UNHEX()
для значения столбца вернет NULL .
Для числового параметра N , инверсия
HEX(N )
не выполнена UNHEX()
. Используйте CONV(HEX(
N ), 16, 10) .
UPPER(str )
Возвращает строку str со всеми символами,
измененными в верхний регистр согласно текущему отображению набора символов.
Значение по умолчанию latin1 (cp1252 West European).
mysql> SELECT UPPER('Hej');
-> 'HEJ'
UCASE() , используемая в пределах представлений,
переписана как UPPER() .
WEIGHT_STRING(str
[AS {CHAR|BINARY}(N )] [LEVEL
levels ] [flags ])
levels :
N [ASC|DESC|REVERSE] [,
N [ASC|DESC|REVERSE]] ...
Эта функция возвращает строку веса для строки ввода. Возвращаемое значение
двоичная строка, которая представляет сравнение и значение сортировки строки.
У нее есть эти свойства:
WEIGHT_STRING()
может использоваться для тестирования и отладки сопоставлений, особенно
если Вы добавляете новое сопоставление. См.
раздел 11.4.
Строка ввода str это строковое выражение. Если ввод
недвоичная (символьная) строка, такая как
CHAR ,
VARCHAR или
TEXT ,
возвращаемое значение содержит вес сопоставления для строки. Если ввод
двоичная строка, такая как
BINARY ,
VARBINARY или
BLOB ,
возвращаемое значение то же самое, как и ввод (вес для каждого байта в
двоичной строке это значение байта). Если ввод NULL ,
WEIGHT_STRING()
тоже вернет NULL . Например:
mysql> SET @s = _latin1 'AB' COLLATE latin1_swedish_ci;
mysql> SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+----+---------+------------------------+
| @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) |
+----+---------+------------------------+
| AB | 4142 | 4142 |
+----+---------+------------------------+
mysql> SET @s = _latin1 'ab' COLLATE latin1_swedish_ci;
mysql> SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+----+---------+------------------------+
| @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) |
+----+---------+------------------------+
| ab | 6162 | 4142 |
+----+---------+------------------------+
mysql> SET @s = CAST('AB' AS BINARY);
mysql> SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+----+---------+------------------------+
| @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) |
+----+---------+------------------------+
| AB | 4142 | 4142 |
+----+---------+------------------------+
mysql> SET @s = CAST('ab' AS BINARY);
mysql> SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+----+---------+------------------------+
| @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) |
+----+---------+------------------------+
| ab | 6162 | 6162 |
+----+---------+------------------------+
Предыдущее использование в качестве примера
HEX() отобразит результат
WEIGHT_STRING() .
Поскольку результат двоичное значение,
HEX()
может быть особенно полезной, когда результат содержит непечатаемые значения,
чтобы вывести на экран это в пригодной для печати форме:
mysql> SET @s = CONVERT(X'C39F' USING utf8) COLLATE utf8_czech_ci;
mysql> SELECT HEX(WEIGHT_STRING(@s));
+------------------------+
| HEX(WEIGHT_STRING(@s)) |
+------------------------+
| 0FEA0FEA |
+------------------------+
Для возвращаемых значений не-NULL тип данных значения
VARBINARY , если его
длина в пределах максимальной длины для
VARBINARY ,
иначе тип данных BLOB .
AS может быть дан, чтобы привести строку ввода к недвоичной
или двоичной строке и нужной длине:
AS CHAR(N ) приводит
строку к недвоичной строке и дополняет справа пробелами до длины
N символов. N должен быть по
крайней мере 1. Если N меньше, чем длина строки ввода,
строка будет усечена до N символов. Никакого
предупреждения не происходит для усечения.
AS BINARY(N ) подобно, но приводит
строку к двоичной строке N измерен в байтах (не
символах!), и дополнение использует байт 0x00 (не пробелы!).
mysql> SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4)));
+-------------------------------------+
| HEX(WEIGHT_STRING('ab' AS CHAR(4))) |
+-------------------------------------+
| 41422020 |
+-------------------------------------+
mysql> SELECT HEX(WEIGHT_STRING('ab' AS BINARY(4)));
+---------------------------------------+
| HEX(WEIGHT_STRING('ab' AS BINARY(4))) |
+---------------------------------------+
| 61620000 |
+---------------------------------------+
LEVEL может быть дан, чтобы определить, что возвращаемое
значение должно содержать веса для определенных уровней сопоставления.
Спецификатор levels после ключевого слова
LEVEL может быть дан как список из одного или более целых чисел,
отделенных запятыми, или как диапазон двух целых чисел, отделенных тире.
Пробелы вокруг символов пунктуации не имеют значения.
Примеры:
LEVEL 1
LEVEL 2, 3, 5
LEVEL 1-3
Любой уровень меньше 1 обработан как 1. Любой уровень больше, чем максимум
для сопоставления строки ввода, обработан как максимум для сопоставления.
Максимум изменяется в зависимости от сопоставление, но никогда не больше 6.
В списке уровни должны быть даны в увеличивающемся порядке. В диапазоне
уровней, если второе число меньше, чем первое, оно обработано как первое
число (например, 4-2 то же самое, что и 4-4).
Если пропущен LEVEL , MySQL принимает
LEVEL 1 - max , где
max максимальный уровень для сопоставления.
Если LEVEL определен, используя синтаксис списка (не
диапазон), любое число уровня может сопровождаться этими модификаторами:
Примеры:
mysql> SELECT HEX(WEIGHT_STRING(0x007fff LEVEL 1));
+--------------------------------------+
| HEX(WEIGHT_STRING(0x007fff LEVEL 1)) |
+--------------------------------------+
| 007FFF |
+--------------------------------------+
mysql> SELECT HEX(WEIGHT_STRING(0x007fff LEVEL 1 DESC));
+-------------------------------------------+
| HEX(WEIGHT_STRING(0x007fff LEVEL 1 DESC)) |
+-------------------------------------------+
| FF8000 |
+-------------------------------------------+
mysql> SELECT HEX(WEIGHT_STRING(0x007fff LEVEL 1 REVERSE));
+----------------------------------------------+
| HEX(WEIGHT_STRING(0x007fff LEVEL 1 REVERSE)) |
+----------------------------------------------+
| FF7F00 |
+----------------------------------------------+
mysql> SELECT HEX(WEIGHT_STRING(0x007fff LEVEL 1 DESC REVERSE));
+---------------------------------------------------+
| HEX(WEIGHT_STRING(0x007fff LEVEL 1 DESC REVERSE)) |
+---------------------------------------------------+
| 0080FF |
+---------------------------------------------------+
flags в настоящее время не используется.
13.5.1. Функции сравнения строк
Таблица 13.8.
Функции сравнения строк
Имя | Описание |
LIKE
| Простое соответствие образцу |
NOT LIKE
| Отрицание простого соответствия образца |
STRCMP()
| Сравнивает две строки |
Если строковой функции дают двоичную строку как параметр, получающаяся
строка также двоичная. Число, преобразованное в строку, обработано как
двоичная строка. Это затрагивает только сравнения.
Обычно если какое-либо выражение в строковом сравнении является
чувствительным к регистру, сравнение выполнено
чувствительным к регистру способом.
expr
LIKE pat [ESCAPE 'escape_char
']
Соответствие образца, используя образец SQL. Возвращает
1 (TRUE ) или 0 (FALSE ).
Если expr или pat
NULL , результат NULL .
Образец не должен быть буквальной строкой. Например, это может быть
определено как строковое выражение или столбец таблицы.
По стандарту SQL LIKE
выполняет соответствие на посимвольном основании, таким образом это может
привести к результатам, отличающимся от оператора сравнения
= :
mysql> SELECT 'ц╓' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ц╓' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
| 0 |
+-----------------------------------------+
mysql> SELECT 'ц╓' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ц╓' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
| 1 |
+--------------------------------------+
В частности конечные пробелы являются существенными, что неверно для
сравнения CHAR или
VARCHAR с помощью
= :
mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
С LIKE
Вы можете использовать следующие два подстановочных символа в образце:
mysql> SELECT 'David!' LIKE 'David_';
-> 1
mysql> SELECT 'David!' LIKE '%D%v%';
-> 1
Чтобы проверить на буквальные случаи подстановочного символа, поставьте
перед ним символ экранирования. Если Вы не определяете символ
ESCAPE , по умолчанию используется \ .
mysql> SELECT 'David!' LIKE 'David\_';
-> 0
mysql> SELECT 'David_' LIKE 'David\_';
-> 1
Чтобы определить иной символ ESC,
используйте определение ESCAPE :
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
-> 1
Escape-последовательность должна быть пустой или одним символом. Выражение
должно оцениваться как константа во время выполнения. Если режим SQL
NO_BACKSLASH_ESCAPES
включен, последовательность не может быть пустой.
Следующие два запроса иллюстрируют, что строковые сравнения не являются
чувствительными к регистру, если один из операндов не чувствителен к регистру
(использует чувствительное к регистру сопоставление или двоичную строку):
mysql> SELECT 'abc' LIKE 'ABC';
-> 1
mysql> SELECT 'abc' LIKE _latin1 'ABC' COLLATE latin1_general_cs;
-> 0
mysql> SELECT 'abc' LIKE _latin1 'ABC' COLLATE latin1_bin;
-> 0
mysql> SELECT 'abc' LIKE BINARY 'ABC';
-> 0
Как расширение к стандартному SQL, MySQL допускает
LIKE
по числовым выражениям.
mysql> SELECT 10 LIKE '1%';
-> 1
Поскольку MySQL использует синтаксис escape C в строках (например,
\n кодирует символ новой строки), Вы должны удвоить любой
\ , который используете в строке
LIKE .
Например, чтобы искать \n , укажите \\n .
Чтобы искать \ , определите это как \\\\ ,
это потому что наклонные черты влево обрезаны сначала анализатором, а потом
когда соответствие образца сделано, оставляя единственную наклонную черту
влево, которая будет соответствующей.
Исключение: В конце строки образца наклонная черта влево может быть
определена как \\ . В конце строки наклонная черта влево
обозначает себя, потому что нет ничего после нее. Предположите, что таблица
содержит следующие значения:
mysql> SELECT filename FROM t1;
+--------------+
| filename |
+--------------+
| C: |
| C:\ |
| C:\Programs |
| C:\Programs\ |
+--------------+
Чтобы проверить на значения, которые заканчиваются наклонной чертой влево,
Вы можете соответствовать значениям, используя любой из следующих образцов:
mysql> SELECT filename, filename LIKE '%\\' FROM t1;
+--------------+---------------------+
| filename | filename LIKE '%\\' |
+--------------+---------------------+
| C: | 0 |
| C:\ | 1 |
| C:\Programs | 0 |
| C:\Programs\ | 1 |
+--------------+---------------------+
mysql> SELECT filename, filename LIKE '%\\\\' FROM t1;
+--------------+-----------------------+
| filename | filename LIKE '%\\\\' |
+--------------+-----------------------+
| C: | 0 |
| C:\ | 1 |
| C:\Programs | 0 |
| C:\Programs\ | 1 |
+--------------+-----------------------+
expr
NOT LIKE pat [ESCAPE
'escape_char ']
Это аналогично NOT (expr LIKE
pat [ESCAPE 'escape_char '])
.
Совокупное вовлечение запросов
NOT LIKE сравнения со столбцами, содержащими
NULL может привести к неожиданным результатам.
Например, рассмотрите следующую таблицу и данные:
CREATE TABLE foo (bar VARCHAR(10));
INSERT INTO foo VALUES (NULL), (NULL);
Запрос SELECT COUNT(*) FROM foo WHERE bar LIKE '%baz%';
вернет 0 . Вы могли бы принять, что SELECT COUNT(*) FROM
foo WHERE bar NOT LIKE '%baz%'; должен вернуть 2 .
Однако, дело обстоит не так: второй запрос вернет 0 .
Это потому, что NULL NOT LIKE
expr всегда возвращает NULL ,
независимо от значения expr .
То же самое истина для совокупного вовлечения запросов
NULL и использования сравнений
NOT
RLIKE или NOT
REGEXP . В таких случаях Вы должны проверить явно на NOT
NULL с помощью OR (но
не AND ):
SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%' OR bar IS NULL;
STRCMP(expr1 ,
expr2 )
STRCMP() вернет
0 , если строки одинаковы, -1 , если первый параметр
меньше второго, согласно текущему порядку сортировки, иначе 1 .
mysql> SELECT STRCMP('text', 'text2');
-> -1
mysql> SELECT STRCMP('text2', 'text');
-> 1
mysql> SELECT STRCMP('text', 'text');
-> 0
STRCMP()
выполняет сравнение, используя сопоставление параметров.
mysql> SET @s1 = _latin1 'x' COLLATE latin1_general_ci;
mysql> SET @s2 = _latin1 'X' COLLATE latin1_general_ci;
mysql> SET @s3 = _latin1 'x' COLLATE latin1_general_cs;
mysql> SET @s4 = _latin1 'X' COLLATE latin1_general_cs;
mysql> SELECT STRCMP(@s1, @s2), STRCMP(@s3, @s4);
+------------------+------------------+
| STRCMP(@s1, @s2) | STRCMP(@s3, @s4) |
+------------------+------------------+
| 0 | 1 |
+------------------+------------------+
Если сопоставления являются несовместимыми, один из параметров должен быть
преобразован, чтобы быть совместимым с другим. См.
раздел 11.1.8.4.
mysql> SELECT STRCMP(@s1, @s3);
ERROR 1267 (HY000): Illegal mix of collations (latin1_general_ci,IMPLICIT)
and (latin1_general_cs,IMPLICIT) for operation 'strcmp'
mysql> SELECT STRCMP(@s1, @s3 COLLATE latin1_general_ci);
+--------------------------------------------+
| STRCMP(@s1, @s3 COLLATE latin1_general_ci) |
+--------------------------------------------+
| 0 |
+--------------------------------------------+
13.5.2. Регулярные выражения
Таблица 13.9.
Строки регулярных выражений
Имя | Описание |
NOT
REGEXP | Отрицание REGEXP |
REGEXP
| Соответствие образца, используя регулярные выражения |
RLIKE
| Синоним для REGEXP |
Регулярное выражение сильный способ определить образец для сложного поиска.
MySQL применяет реализацию регулярных выражений от Henry Spencer,
которая нацелена на соответствие POSIX 1003.2. MySQL использует расширенную
версию, чтобы поддержать соответствующие образцы, выполненные оператором
REGEXP в запросах SQL.
Этот раздел подводит итог, с примерами, специальными символами и
конструкциями, которые могут использоваться в MySQL для
REGEXP .
Это не содержит все детали, которые могут быть найдены в
Henry Spencer's regex(7) manual page. Эта документация есть в
дистрибутиве исходных текстов MySQL в файле regex.7 каталога
regex . Также изучите
раздел 4.3.4.7.
Операторы регулярных выражений
expr
NOT REGEXP pat ,
expr
NOT RLIKE pat
Аналог NOT (expr REGEXP
pat ) .
expr
REGEXP pat ,
expr
RLIKE pat
Выполняет соответствие образца строкового выражения
expr шаблону pat .
Образец может быть расширенным регулярным выражением, синтаксис для которого
рассмотрен позже в этом разделе. Возвращает
1 , если expr соответствует
pat , иначе 0 . Если
expr или pat NULL ,
результат NULL . RLIKE
синоним для REGEXP
для совместимости с mSQL .
Образец не должен быть буквальной строкой. Например, это может быть
определено как строковое выражение или столбец таблицы.
Поскольку MySQL использует синтаксис escape C в строках (например,
\n означает новую строку), Вы должны удвоить любой
\ , который Вы используете в Вашей строке
REGEXP .
REGEXP
не является чувствительной к регистру, кроме тех случаев, когда
используется с двоичными строками.
mysql> SELECT 'Monty!' REGEXP '.*';
-> 1
mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
-> 1
mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
-> 1 0
mysql> SELECT 'a' REGEXP '^[a-d]';
-> 1
REGEXP и
RLIKE
используют набор символов и сопоставления параметров, определяя тип символа и
выполняя сравнение. Если у параметров есть различные наборы символов или
сопоставления, правила применяются как описано в
разделе 11.1.8.4.
Операторы REGEXP и
RLIKE
работают побайтно, таким образом, они не безопасны для мультибайтных символов
и могут привести к неожиданным результатам с многобайтовыми символами. Кроме
того, эти операторы сравнивают символы по их байтовым значениям и некоторые
символы, возможно, не сравниваются как равные, даже если данное сопоставление
обрабатывает их как равных.
Синтаксис регулярных выражений
Регулярное выражение описывает ряд строк. Самое простое регулярное
выражение то, у которого нет никаких специальных символов в нем. Например,
регулярное выражение hello соответствует только
hello и ничему больше.
Нетривиальные регулярные выражения используют определенные специальные
конструкции так, чтобы они могли соответствовать больше, чем одной строке.
Например, регулярное выражение hello|word соответствует любой
строке hello или word .
Как более сложный пример, регулярное выражение
B[an]*s соответствует любой из строк
Bananas , Baaaaas , Bs и
любой другой строке, начинающейся с B , заканчивающейся на
s и включающей любое число символов a
или n между ними.
Регулярное выражение для
REGEXP может использовать любой из следующих
специальных символов и конструкций:
^
Соответствует началу строки.
mysql> SELECT 'fo\nfo' REGEXP '^fo$';
-> 0
mysql> SELECT 'fofo' REGEXP '^fo';
-> 1
$
Конец строки.
mysql> SELECT 'fo\no' REGEXP '^fo\no$';
-> 1
mysql> SELECT 'fo\no' REGEXP '^fo$';
-> 0
.
Соответствует любому символу (включая возврат каретки и новую строку).
mysql> SELECT 'fofo' REGEXP '^f.*$';
-> 1
mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$';
-> 1
a*
Соответствует любой последовательности из ноля или больше символов
a .
mysql> SELECT 'Ban' REGEXP '^Ba*n';
-> 1
mysql> SELECT 'Baaan' REGEXP '^Ba*n';
-> 1
mysql> SELECT 'Bn' REGEXP '^Ba*n';
-> 1
a+
Соответствует любой последовательности из одного или больше символов
a .
mysql> SELECT 'Ban' REGEXP '^Ba+n';
-> 1
mysql> SELECT 'Bn' REGEXP '^Ba+n';
-> 0
a?
Соответствует нолю или одному символу a .
mysql> SELECT 'Bn' REGEXP '^Ba?n';
-> 1
mysql> SELECT 'Ban' REGEXP '^Ba?n';
-> 1
mysql> SELECT 'Baan' REGEXP '^Ba?n';-> 0
de|abc
Соответствует любой из последовательностей
de или abc .
mysql> SELECT 'pi' REGEXP 'pi|apa';
-> 1
mysql> SELECT 'axe' REGEXP 'pi|apa';
-> 0
mysql> SELECT 'apa' REGEXP 'pi|apa';
-> 1
mysql> SELECT 'apa' REGEXP '^(pi|apa)$';
-> 1
mysql> SELECT 'pi' REGEXP '^(pi|apa)$';
-> 1
mysql> SELECT 'pix' REGEXP '^(pi|apa)$';
-> 0
(abc)*
Соответствует нолю или больше экземпляров последовательности
abc .
mysql> SELECT 'pi' REGEXP '^(pi)*$';
-> 1
mysql> SELECT 'pip' REGEXP '^(pi)*$';
-> 0
mysql> SELECT 'pipi' REGEXP '^(pi)*$';
-> 1
{1} , {2,3}
Нотация {n} или {m,n}
обеспечивает более общий способ написать регулярные выражения, которые
соответствуют нескольким возникновениям предыдущего атома (или
куска) шаблона. m и n целые числа.
a*
Может быть написан как a{0,} .
a+
Может быть написан как a{1,} .
a?
Может быть написан как a{0,1} .
Более точно a{n} соответствует
n экземплярам a . a{n,} соответствует
n или больше экземплярам a .
a{m,n} соответствует от m
до n экземплярам a , включительно.
m и n должны быть в диапазоне от
0 до RE_DUP_MAX (значение по умолчанию 255),
включительно. Если оба m и n заданы,
m должно быть меньше или равным n .
mysql> SELECT 'abcde' REGEXP 'a[bcd]{2}e';
-> 0
mysql> SELECT 'abcde' REGEXP 'a[bcd]{3}e';
-> 1
mysql> SELECT 'abcde' REGEXP 'a[bcd]{1,10}e';
-> 1
[a-dX] , [^a-dX]
Соответствует любому символу, который является (или нет, если ^
используется), a , b , c , d
или X . Символ - между двумя другими символами
формирует диапазон, который соответствует всем символам от первого до
второго. Например, [0-9] соответствует любой десятичной цифре.
Чтобы включить символ ] , он должен немедленно следовать за
вводной скобкой [ . Чтобы включить символ - , он
должен быть написан сначала или последним. Любой символ, у которого нет
определенного особого значения внутри пары [] соответствует
только себе самому.
mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]';
-> 1
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$';
-> 0
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$';
-> 1
mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$';
-> 0
mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$';
-> 1
mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$';
-> 0
[.characters.]
В пределах выражения скобки ([ и ] )
соответствует последовательности символов того элемента сопоставления.
characters единственный символ или имя символа, например,
newline . Следующая таблица приводит допустимые имена.
Следующая таблица показывает допустимые имена и символы, которым
они соответствуют. Для символов, данных как числовые значения, их значения
представлены как октальные.
Имя | Символ |
Имя | Символ |
NUL | 0 |
SOH | 001 |
STX | 002 |
ETX | 003 |
EOT | 004 |
ENQ | 005 |
ACK | 006 |
BEL | 007 |
alert | 007 |
BS | 010 |
backspace | '\b' |
HT | 011 |
tab | '\t' |
LF | 012 |
newline | '\n' |
VT | 013 |
vertical-tab | '\v' |
FF | 014 |
form-feed | '\f' |
CR | 015 |
carriage-return |
'\r' | SO |
016 |
SI | 017 |
DLE | 020 |
DC1 | 021 |
DC2 | 022 |
DC3 | 023 |
DC4 | 024 |
NAK | 025 |
SYN | 026 |
ETB | 027 |
CAN | 030 |
EM | 031 |
SUB | 032 |
ESC | 033 |
IS4 | 034 |
FS | 034 |
IS3 | 035 |
GS | 035 |
IS2 | 036 |
RS | 036 |
IS1 | 037 |
US | 037 |
space | ' ' |
exclamation-mark |
'!' | quotation-mark |
'"' |
number-sign | '#' |
dollar-sign | '$' |
percent-sign | '%' |
ampersand | '&' |
apostrophe | '\'' |
left-parenthesis | '(' |
right-parenthesis |
')' | asterisk |
'*' |
plus-sign | '+' |
comma | ',' |
hyphen | '-' |
hyphen-minus | '-' |
period | '.' |
full-stop | '.' |
slash | '/' |
solidus | '/' |
zero | '0' |
one | '1' |
two | '2' |
three | '3' |
four | '4' |
five | '5' |
six | '6' |
seven | '7' |
eight | '8' |
nine | '9' |
colon | ':' |
semicolon | ';' |
less-than-sign |
'<' | equals-sign |
'=' |
greater-than-sign |
'>' | question-mark |
'?' |
commercial-at | '@' |
left-square-bracket | '[' |
backslash | '\\' |
reverse-solidus | '\\' |
right-square-bracket |
']' | circumflex |
'^' |
circumflex-accent |
'^' | underscore |
'_' |
low-line | '_' |
grave-accent | '`' |
left-brace | '{' |
left-curly-bracket | '{' |
vertical-line | '|' |
right-brace | '}' |
right-curly-bracket |
'}' | tilde | '~' |
DEL | 177 | |
|
mysql> SELECT '~' REGEXP '[[.~.]]';
-> 1
mysql> SELECT '~' REGEXP '[[.tilde.]]';
-> 1
[=character_class=]
В пределах выражения скобки ([ и ] )
[=character_class=] представляет класс эквивалентности. Это
соответствует все символы с тем же самым значением сопоставления, включая
себя. Например, если o и (+) члены класса
эквивалентности, [[=o=]] , [[=(+)=]] и
[o(+)] синонимы. Класс эквивалентности не может использоваться в
качестве конечной точки диапазона.
[:character_class:]
В пределах выражения скобки ([ и ] )
[:character_class:] представляет символьный класс, который
соответствует всем символам, принадлежащим этому классу. Следующая таблица
приводит стандартные названия классов. Эти имена обозначают символьные
классы, определенные в ctype(3) . Особое место действия
может обеспечить другие названия классов. Символьный класс не может
использоваться в качестве конечной точки диапазона.
Имя класса символов | Смысл |
alnum | Алфавитно-цифровые
символы |
alpha | Буквенные символы |
blank | Пробелы |
cntrl | Символы управления |
digit | Цифры |
graph | Графические символы |
lower | Строчные буквенные символы
|
print | Графические символы или пробелы
|
punct | Символы пунктуации |
space | Пробел, табуляция, новая
строка и возврат каретки |
upper |
Буквенные символы верхнего регистра |
xdigit | Шестнадцатеричные цифры
|
mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+'; -> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]]+'; -> 0
[[:<:]] , [[:>:]]
Эти маркеры обозначают границы слова. Они соответствуют началу
и концу слов, соответственно. Слово последовательность символов слова,
которой не предшествуют или сопровождается символами слова. Символ слова
буквенно-цифровой знак в классе alnum или подчеркивание
(_ ).
mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]';
-> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]';
-> 0
Чтобы использовать буквальный случай специального символа в регулярном
выражении, предварите его двумя наклонными чертами влево (\\). Анализатор
MySQL интерпретирует одну из наклонных черт влево, а библиотека регулярных
выражений интерпретирует другую. Например, чтобы соответствовать строке
1+2 , которая содержит специальный символ
+ , только последнее из следующих регулярных
выражений является правильным:
mysql> SELECT '1+2' REGEXP '1+2';
-> 0
mysql> SELECT '1+2' REGEXP '1\+2';
-> 0
mysql> SELECT '1+2' REGEXP '1\\+2';
-> 1
13.5.3.
Набор символов и сопоставление функциональных результатов
У MySQL есть много операторов и функций, которые возвращают строку. Этот
раздел отвечает на вопрос: каков набор символов и сопоставление такой строки?
Для простых функций, которые берут строковый ввод и возвращают строковый
результат как выход, набор символов вывода и сопоставление те же самые, что и
таковые из входного значения. Например,
UPPER(X )
возвращает строку с той же самой строкой символов и
сопоставлением как было в X .
То же самое касается функций
INSTR() ,
LCASE() ,
LOWER() ,
LTRIM() ,
MID() ,
REPEAT() ,
REPLACE() ,
REVERSE() ,
RIGHT() ,
RPAD() ,
RTRIM() ,
SOUNDEX() ,
SUBSTRING() ,
TRIM() ,
UCASE() и
UPPER() .
Функция REPLACE() ,
в отличие от всех других функций, всегда игнорирует сопоставление строкового
ввода и выполняет чувствительное к регистру сравнение.
Если строковый ввод или функциональный результат двоичная строка, она
имеет набор символов и сопоставление binary .
Это может быть проверено при использовании функций
CHARSET() и
COLLATION() ,
обе из которых возвращают binary
для двоичного строкового параметра:
mysql> SELECT CHARSET(BINARY 'a'), COLLATION(BINARY 'a');
+---------------------+-----------------------+
| CHARSET(BINARY 'a') | COLLATION(BINARY 'a') |
+---------------------+-----------------------+
| binary | binary |
+---------------------+-----------------------+
Для операций, которые комбинируют много строк и возвращают единственный
строковый вывод, используются правила агрегации
стандартного SQL для определения сопоставления результата:
Например, с CASE ... WHEN a THEN b WHEN b THEN c
COLLATE X END , получающееся сопоставление
X . То же самое касается
UNION ,
|| ,
CONCAT() ,
ELT() ,
GREATEST() ,
IF() и
LEAST() .
Для операций, которые преобразовывают в символьные данные, набор символов
и сопоставление строк, которые следуют из операций, определены переменными
character_set_connection и
collation_connection
, которые определяют набор символов и сопоставление соединения по
умолчанию (см. раздел 11.1.4).
Это применяется только к
CAST() ,
CONV() ,
FORMAT() ,
HEX() и
SPACE() .
Если есть вопрос о наборе символов или сопоставлении результата,
возвращенного строковой функцией, используйте функцию
CHARSET() или
COLLATION()
, чтобы узнать:
mysql> SELECT USER(), CHARSET(USER()), COLLATION(USER());
+----------------+-----------------+-------------------+
| USER() | CHARSET(USER()) | COLLATION(USER()) |
+----------------+-----------------+-------------------+
| test@localhost | utf8 | utf8_general_ci |
+----------------+-----------------+-------------------+
mysql> SELECT CHARSET(COMPRESS('abc')), COLLATION(COMPRESS('abc'));
+--------------------------+----------------------------+
| CHARSET(COMPRESS('abc')) | COLLATION(COMPRESS('abc')) |
+--------------------------+----------------------------+
| binary | binary |
+--------------------------+----------------------------+
13.6. Числовые функции и операторы
Таблица 13.10. Числовые функции и операторы
Имя | Описание |
ABS()
| Возвращает абсолютное значение |
ACOS()
| Возвращает арккосинус |
ASIN()
| Арксинус |
ATAN()
| Арктангенс |
ATAN2() ,
ATAN() | Арктангенс двух параметров |
CEIL()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CEILING()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CONV()
| Преобразует числа между системами счисления |
COS()
| Косинус |
COT()
| Котангенс |
CRC32()
| Значение циклического контроля по избыточности |
DEGREES()
| Конвертирует радианы в degrees |
DIV
| Целочисленное деление |
/
| Оператор деления |
EXP()
| Возведение в степень |
FLOOR()
| Самое большое целочисленное значение, не больше, чем параметр
|
LN()
| Натуральный логарифм |
LOG()
| Натуральный логарифм первого параметра |
LOG10()
| Десятичный логарифм |
LOG2()
| Двоичный логарифм |
-
| Оператор "-" |
MOD()
| Остаток |
% ,
MOD | Модуль |
PI()
| Значение числа pi |
+ |
Оператор "+" |
POW()
| Возводит в указанную степень |
POWER()
| Возводит в указанную степень |
RADIANS()
| Конвертирует в радианы |
RAND()
| Возвратит случайное значение с плавающей запятой |
ROUND()
| Округлит параметр |
SIGN()
| Знак аргумента |
SIN()
| Синус |
SQRT()
| Квадратный корень параметра |
TAN()
| Тангенс |
*
| Умножение |
TRUNCATE()
| Урезает к конкретному количеству десятичных разрядов
|
-
| Меняет знак аргумента |
13.6.1. Арифметические операторы
Таблица 13.11. Арифметические операторы
Имя | Описание |
DIV
| Целочисленное деление |
/
| Оператор деления |
-
| Оператор "-" |
% ,
MOD | Модуль |
+ |
Оператор "+" |
*
| Умножение |
-
| Меняет знак аргумента |
Обычные арифметические операторы доступны. Результат определен
согласно следующим правилам:
Эти правила применены для каждой операции так, что вложенные вычисления
подразумевают точность каждого компонента. Следовательно,
(14620 / 9432456) / (24250 / 9432456) сначала сведется к
(0.0014) / (0.0026) с окончательным результатом, имеющим 8
десятичных разрядов (0.60288653 ).
Из-за этих правил надо следить за тем, что компоненты и субкомпоненты
вычисления используют соответствующий уровень точности. См.
раздел 13.10.
Арифметические операторы обращаются к числам. Для других типов значений
альтернативные операции могут быть доступны. Например, чтобы добавить
значения даты, используйте
DATE_ADD() .
+
Сложение:
mysql> SELECT 3+5;
-> 8
-
Вычитание:
mysql> SELECT 3-5;
-> -2
-
Одноместный минус. Этот оператор изменяет знак операнда.
mysql> SELECT - 2;
-> -2
Если этот оператор используется с
BIGINT ,
возвращаемое значение также BIGINT
. Это означает, что Вы должны избегать использования
- на целых числах, у которых может быть значение 263.
*
Умножение:
mysql> SELECT 3*5;
-> 15
mysql> SELECT 18014398509481984*18014398509481984.0;
-> 324518553658426726783156020576256.0
mysql> SELECT 18014398509481984*18014398509481984;
-> out-of-range error
Последнее выражение производит ошибку, потому что результат умножения
целого числа превышает 64-битный диапазон
BIGINT . См.
раздел 12.2.
/
Деление:
mysql> SELECT 3/5;
-> 0.60
Деление на ноль вернет NULL :
mysql> SELECT 102/(1-1);
-> NULL
Деление вычислено с арифметикой
BIGINT
только если выполнено в контексте, где его результат
преобразован в целое число.
DIV
Деление целого числа. Результат заканчивается любой дробной частью справа
от десятичной запятой.
Если у любого операнда есть тип нецелого числа, операнды преобразованы в
DECIMAL и делятся с
использованием арифметики DECIMAL
прежде, чем преобразовать результат в
BIGINT .
Если результат превышает диапазон BIGINT , будет ошибка.
mysql> SELECT 5 DIV 2, -5 DIV 2, 5 DIV -2, -5 DIV -2;
-> 2, -2, -2, 2
N
% M ,
N
MOD M
Остаток. Возвращает остаток от деления N на
M .
13.6.2. Математические функции
Таблица 13.12. Математические функции
Имя | Описание
|
ABS()
| Возвращает абсолютное значение |
ACOS()
| Возвращает арккосинус |
ASIN()
| Арксинус |
ATAN()
| Арктангенс |
ATAN2() ,
ATAN() | Арктангенс двух параметров |
CEIL()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CEILING()
| Возвратить самое маленькое целочисленное значение
не меньше, чем параметр |
CONV()
| Преобразует числа между системами счисления |
COS()
| Косинус |
COT()
| Котангенс |
CRC32()
| Значение циклического контроля по избыточности |
DEGREES()
| Конвертирует радианы в degrees |
EXP()
| Возведение в степень |
FLOOR()
| Самое большое целочисленное значение, не больше, чем параметр
|
LN()
| Натуральный логарифм |
LOG()
| Натуральный логарифм первого параметра |
LOG10()
| Десятичный логарифм |
LOG2()
| Двоичный логарифм |
MOD()
| Остаток |
PI()
| Значение числа pi |
POW()
| Возводит в указанную степень |
POWER()
| Возводит в указанную степень |
RADIANS()
| Конвертирует в радианы |
RAND()
| Возвратит случайное значение с плавающей запятой |
ROUND()
| Округлит параметр |
SIGN()
| Знак аргумента |
SIN()
| Синус |
SQRT()
| Квадратный корень параметра |
TAN()
| Тангенс |
TRUNCATE()
| Урезает к конкретному количеству десятичных разрядов
|
Все математические функции вернут NULL в случае ошибки.
ABS(X )
Возвращает абсолютное значение X .
mysql> SELECT ABS(2);
-> 2
mysql> SELECT ABS(-32);
-> 32
Эту функцию безопасно использовать с
BIGINT .
ACOS(X )
Возвращает арккосинус X то есть, значение, косинус
которого X . Вернет NULL , если
X не находится в диапазоне
от -1 до 1 .
mysql> SELECT ACOS(1);
-> 0
mysql> SELECT ACOS(1.0001);
-> NULL
mysql> SELECT ACOS(0);
-> 1.5707963267949
ASIN(X )
Возвращает арксинус X то есть, значение, синус
которого X . Вернет NULL , если
X не находится в диапазоне
от -1 до 1 .
mysql> SELECT ASIN(0.2);
-> 0.20135792079033
mysql> SELECT ASIN('foo');
+-------------+
| ASIN('foo') |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' |
+---------+------+-----------------------------------------+
ATAN(X )
Возвращает арктангенс X ,
то есть, значение, тангенс которого X .
mysql> SELECT ATAN(2);
-> 1.1071487177941
mysql> SELECT ATAN(-2);
-> -1.1071487177941
ATAN(Y ,
X ) ,
ATAN2(Y ,
X )
Возвращает арктангенс этих двух переменных
X и Y .
Это подобно вычислению арктангенса
Y /X ,
за исключением того, что знаки обоих параметров используются, чтобы
определить сектор результата.
mysql> SELECT ATAN(-2,2);
-> -0.78539816339745
mysql> SELECT ATAN2(PI(),0);
-> 1.5707963267949
CEIL(X )
CEIL() синоним для
CEILING() .
CEILING(X )
Возвращает самое маленькое целочисленное значение не меньше
X .
mysql> SELECT CEILING(1.23);
-> 2
mysql> SELECT CEILING(-1.23);
-> -1
Для числовых параметров точного значения у возвращаемого значения будет
числовой тип точного значения. Для строки или параметров с плавающей запятой
у возвращаемого значения будет тип с плавающей запятой.
CONV(N ,
from_base ,to_base )
Конвертирует между различными основаниями системы счисления. Возвращает
строковое представление числа N ,
преобразованного из основы from_base в
to_base . Возвращает NULL ,
если какой-либо параметр NULL . Параметр N
интерпретируется как целое число, но может быть определен как целое число или
строка. Минимальная основа 2 максимальная 36 .
Если from_base отрицательное число,
N расценено как число со знаком. Иначе
N как без знака.
CONV() работает с 64-битной точностью.
mysql> SELECT CONV('a',16,2);
-> '1010'
mysql> SELECT CONV('6E',18,8);
-> '172'
mysql> SELECT CONV(-17,10,-18);
-> '-H'
mysql> SELECT CONV(10+'10'+'10'+X'0a',10,10);
-> '40'
COS(X )
Возвращает косинус X , где X
задан в радианах.
mysql> SELECT COS(PI());
-> -1
COT(X )
Возвращает котангенс X .
mysql> SELECT COT(12);
-> -1.5726734063977
mysql> SELECT COT(0);
-> NULL
CRC32(expr )
Вычисляет значение циклического контроля по избыточности и возвращает
32-битное значение без знака. Результат NULL , если параметр
NULL . Параметром, как ожидают, будет строка.
mysql> SELECT CRC32('MySQL');
-> 3259397556
mysql> SELECT CRC32('mysql');
-> 2501908538
DEGREES(X )
Возвращает параметр X , преобразованный
из радиан в градусы.
mysql> SELECT DEGREES(PI());
-> 180
mysql> SELECT DEGREES(PI() / 2);
-> 90
EXP(X )
Возвращает значение e (основание натуральных
логарифмов), возведенное в степень X .
Инверсия этой функции LOG()
(с использованием единственного параметра) или
LN() .
mysql> SELECT EXP(2);
-> 7.3890560989307
mysql> SELECT EXP(-2);
-> 0.13533528323661
mysql> SELECT EXP(0);
-> 1
FLOOR(X )
Возвращает самое большое целочисленное значение, не больше
X .
mysql> SELECT FLOOR(1.23), FLOOR(-1.23);
-> 1, -2
Для числовых параметров точного значения у возвращаемого значения будет
числовой тип точного значения. Для строки или параметров с плавающей запятой
у возвращаемого значения будет тип с плавающей запятой.
FORMAT(X ,
D )
Форматирует число X как '#,###,###.##' ,
округляя до D десятичных разрядов и возвращая результат
как строку. Для деталей см. раздел 13.5
.
HEX(N_or_S)
Эта функция может использоваться, чтобы получить шестнадцатеричное
представление десятичного числа или строки. Алгоритм изменяется, согласно
типу параметра. См. описание этой функции в
разделе 13.5.
LN(X )
Возвращает натуральный логарифм X , то есть логарифм
X по основанию e. Если
X меньше или равно 0.0E0, функция вернет
NULL и выдаст предупреждение
Invalid argument for logarithm.
mysql> SELECT LN(2);
-> 0.69314718055995
mysql> SELECT LN(-2);
-> NULL
Эта функция синонимична
LOG(X )
. Инверсия этой функции EXP()
.
LOG(X )
, LOG(B ,
X )
Если вызвана с одним параметром, эта функция возвращает натуральный
логарифм X . Если X меньше или
равно 0.0E0, функция вернет NULL и выдаст предупреждение
Invalid argument for logarithm.
Инверсия этой функции (когда вызвана с единственным параметром)
EXP() .
mysql> SELECT LOG(2);
-> 0.69314718055995
mysql> SELECT LOG(-2);
-> NULL
Если вызвана с двумя параметрами, эта функция возвращает логарифм
X по основанию B . Если
X меньше или равно 0 или B
меньше или равно 1, вернется NULL .
mysql> SELECT LOG(2,65536);
-> 16
mysql> SELECT LOG(10,100);
-> 2
mysql> SELECT LOG(1,100);
-> NULL
LOG(B ,
X ) эквивалентна
LOG(X ) /
LOG(B ) .
LOG2(X )
Возвращает логарифм X по основанию
2. Если X меньше или
равно 0.0E0, функция вернет NULL и выдаст предупреждение
Invalid argument for logarithm.
mysql> SELECT LOG2(65536);
-> 16
mysql> SELECT LOG2(-100);
-> NULL
LOG2()
полезна для обнаружения, какое количество битов число требует для хранения.
Эта функция эквивалентна выражению
LOG(X ) /
LOG(2) .
LOG10(X )
Возвращает логарифм X по основанию
10. Если X меньше или
равно 0.0E0, функция вернет NULL и выдаст предупреждение
Invalid argument for logarithm.
mysql> SELECT LOG10(2);
-> 0.30102999566398
mysql> SELECT LOG10(100);
-> 2
mysql> SELECT LOG10(-100);
-> NULL
LOG10(X )
эквивалентна LOG(10,
X ) .
MOD(N ,
M ) ,
N
% M ,
N
MOD M
Возвращает остаток от деления N на
M .
mysql> SELECT MOD(234, 10);
-> 4
mysql> SELECT 253 % 7;
-> 1
mysql> SELECT MOD(29,9);
-> 2
mysql> SELECT 29 MOD 9;
-> 2
Эту функцию безопасно использовать с
BIGINT .
MOD()
также работает с значениями, которые имеют дробную часть, и возвращает точный
остаток после деления:
mysql> SELECT MOD(34.5,3);
-> 1.5
MOD(N ,0)
вернет NULL .
PI()
Возвращает значение pi. По умолчанию количество выведенных десятичных
разрядов семь, но MySQL использует полное значение точности double внутренне.
mysql> SELECT PI();
-> 3.141593
mysql> SELECT PI()+0.000000000000000000;
-> 3.141592653589793116
POW(X ,
Y )
Возвращает значение X возведенное в степень
Y .
mysql> SELECT POW(2,2);
-> 4
mysql> SELECT POW(2,-2);
-> 0.25
POWER(X ,
Y )
Синоним для POW() .
RADIANS(X )
Возвращает параметр X , преобразованный из градусов
в радианы. Отметьте, что 0 радиан равняется 180 градусов.
mysql> SELECT RADIANS(90);
-> 1.5707963267949
RAND() ,
RAND(N )
Возвращает случайное значение с плавающей запятой
v в диапазоне
0 <= v < 1.0 .
Если постоянный параметр целого числа N указан,
это используется в качестве стартового значения, которое производит
повторимую последовательность значений столбцов. В следующем примере
отметьте, что последовательности значений, произведенных
RAND(3) те же самые.
mysql> CREATE TABLE t (i INT);
Query OK, 0 rows affected (0.42 sec)
mysql> INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT i, RAND() FROM t;
+---+------------------+
| i | RAND() |
+---+------------------+
| 1 | 0.61914388706828 |
| 2 | 0.93845168309142 |
| 3 | 0.83482678498591 |
+---+------------------+
3 rows in set (0.00 sec)
mysql> SELECT i, RAND(3) FROM t;
+---+------------------+
| i | RAND(3) |
+---+------------------+
| 1 | 0.90576975597606 |
| 2 | 0.37307905813035 |
| 3 | 0.14808605345719 |
+---+------------------+
3 rows in set (0.00 sec)
mysql> SELECT i, RAND() FROM t;
+---+------------------+
| i | RAND() |
+---+------------------+
| 1 | 0.35877890638893 |
| 2 | 0.28941420772058 |
| 3 | 0.37073435016976 |
+---+------------------+
3 rows in set (0.00 sec)
mysql> SELECT i, RAND(3) FROM t;
+---+------------------+
| i | RAND(3) |
+---+------------------+
| 1 | 0.90576975597606 |
| 2 | 0.37307905813035 |
| 3 | 0.14808605345719 |
+---+------------------+
3 rows in set (0.01 sec)
С постоянным инициализатором, настройка происходит однократно, до
выполнения запроса. Если непостоянный инициализатор (такой, как имя столбца)
используется в качестве параметра, настройка происходит со значением для
каждого вызова RAND() .
Одно значение этого то, что для равных значений параметра
RAND()
возвратит то же самое значение каждый раз.
Получить случайное целое число R в диапазоне
i <= R <
j можно, используя выражение
FLOOR(i
+ RAND() * (j
i )) . Например, чтобы получить случайное
целое число в диапазоне
7 <= R < 12 ,
Вы можете использовать следующий запрос:
SELECT FLOOR(7 + (RAND() * 5));
RAND() в предложении
WHERE переоценено каждый раз,
когда выполняется WHERE .
Использование столбца с RAND()
в предложении ORDER BY или GROUP BY
может привести к неожиданным результатам потому что для любого запроса
RAND()
может быть оценено несколько раз для той же самой строки, каждый раз
возвращая различный результат. Однако, Вы можете получить
строки в случайном порядке:
mysql> SELECT * FROM tbl_name ORDER BY RAND();
ORDER BY RAND() объединенный с LIMIT полезен
для случайной выборки из ряда строк:
mysql> SELECT * FROM table1, table2 WHERE a=b AND c<d
ORDER BY RAND() LIMIT 1000;
RAND()
не предназначен, чтобы быть прекрасным случайным генератором. Это быстрый
способ произвести случайные числа по требованию, который портативен между
платформами для той же самой версии MySQL.
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
установлено в STATEMENT (Bug #49222).
ROUND(X )
, ROUND(X
, D )
Округляет параметр X до D
десятичных разрядов. Округляющий алгоритм зависит от типа данных
X . D по умолчанию 0, если не
определен. D может быть отрицательным, чтобы
D цифр в X слева от десятичной
точки стали нулями.
mysql> SELECT ROUND(-1.23);
-> -1
mysql> SELECT ROUND(-1.58);
-> -2
mysql> SELECT ROUND(1.58);
-> 2
mysql> SELECT ROUND(1.298, 1);
-> 1.3
mysql> SELECT ROUND(1.298, 0);
-> 1
mysql> SELECT ROUND(23.298, -1);
-> 20
Тип возврата тот же самый тип как у первого параметра (предполагается,
что это целое число, double или decimal). Это означает, что для параметра
целого числа, результат целое число:
mysql> SELECT ROUND(150.000,2), ROUND(150,2);
+------------------+--------------+
| ROUND(150.000,2) | ROUND(150,2) |
+------------------+--------------+
| 150.00 | 150 |
+------------------+--------------+
ROUND()
использует следующие правила в зависимости от типа первого параметра:
Для чисел точного значения
ROUND()
использует правило round half away from zero или round
toward nearest: значение с дробной частью .5 или больше округлено к
следующему целому числу, если положительное, или вниз к следующему целому
числу, если отрицательное. Другими словами, это округлено дальше от ноля.
Значение с дробной частью меньше .5 округлено в меньшую сторону к следующему
целому числу, если положительное, или до следующего целого
числа, если отрицательное.
- Для чисел приблизительной точности результат зависит от библиотеки C. На
многих системах это означает, что
ROUND() использует
правило "round to nearest even": значение с любой дробной частью округлено к
самому близкому целому числу.
Следующие примеры показывают, как округление отличается для
точных и приблизительных чисел:
mysql> SELECT ROUND(2.5), ROUND(25E-1);
+------------+--------------+
| ROUND(2.5) | ROUND(25E-1) |
+------------+--------------+
| 3 | 2 |
+------------+--------------+
SIGN(X )
Возвращает знак параметра как -1 , 0 или
1 , в зависимости от того, каким является X
: отрицательным, нулем или положительным.
mysql> SELECT SIGN(-32);
-> -1
mysql> SELECT SIGN(0);
-> 0
mysql> SELECT SIGN(234);
-> 1
SIN(X )
Возвращает синус X ,
где X дан в радианах.
mysql> SELECT SIN(PI());
-> 1.2246063538224e-16
mysql> SELECT ROUND(SIN(PI()));
-> 0
SQRT(X )
Возвращает квадратный корень неотрицательного числа
X .
mysql> SELECT SQRT(4);
-> 2
mysql> SELECT SQRT(20);
-> 4.4721359549996
mysql> SELECT SQRT(-16);
-> NULL
TAN(X )
Возвращает тангенс X , где
X дан в радианах.
mysql> SELECT TAN(PI());
-> -1.2246063538224e-16
mysql> SELECT TAN(PI()+1);
-> 1.5574077246549
TRUNCATE(X ,
D )
Возвращает число X , усеченное до
D десятичных разрядов. Если
D 0 , у результата нет никакой десятичной
запятой или дробной части. D может быть отрицательным,
чтобы D цифр X слева от
запятой стали нулями.
mysql> SELECT TRUNCATE(1.223,1);
-> 1.2
mysql> SELECT TRUNCATE(1.999,1);
-> 1.9
mysql> SELECT TRUNCATE(1.999,0);
-> 1
mysql> SELECT TRUNCATE(-1.999,1);
-> -1.9
mysql> SELECT TRUNCATE(122,-2);
-> 100
mysql> SELECT TRUNCATE(10.28*100,0);
-> 1028
Все числа округлены к нолю.
13.7. Функции даты и времени
Таблица 13.13. Функции Date/Time
Имя | Описание |
ADDDATE() | Добавляет интервал времени к значению даты
|
ADDTIME()
| Добавляет время |
CONVERT_TZ() | Преобразует временные зоны |
CURDATE()
| Текущяя дата |
CURRENT_DATE() , CURRENT_DATE |
Синоним для CURDATE() |
CURRENT_TIME() , CURRENT_TIME |
Синоним для CURTIME() |
CURRENT_TIMESTAMP() , CURRENT_TIMESTAMP |
Синоним для NOW() |
CURTIME()
| Текущее время |
DATE()
| Извлекает часть даты из date или datetime |
DATE_ADD()
| Добавляет интервал к дате |
DATE_FORMAT() | Форматирует дату как надо |
DATE_SUB()
| Вычитает интервал из даты |
DATEDIFF()
| Вычитает две даты |
DAY()
| Синоним для DAYOFMONTH() |
DAYNAME()
| Название дня |
DAYOFMONTH() | День месяца (0-31) |
DAYOFWEEK()
| День недели (индекс) |
DAYOFYEAR()
| День года (1-366) |
EXTRACT()
| Извлекает часть даты |
FROM_DAYS()
| Конвертирует число дней в дату |
FROM_UNIXTIME() | Форматирует Unix timestamp в дату |
GET_FORMAT() | Дата, сформатированная в строку |
HOUR()
| Извлекает час |
LAST_DAY
| Последний день месяца для параметра |
LOCALTIME()
, LOCALTIME | Синоним для NOW() |
LOCALTIMESTAMP , LOCALTIMESTAMP() |
Синоним для NOW() |
MAKEDATE()
| Создает дату из года и дня года |
MAKETIME()
| Создает время из часа, минуты и секунды |
MICROSECOND() | Возвратит микросекунды из параметра |
MINUTE()
| Минута из параметра |
MONTH()
| Месяц из значения даты |
MONTHNAME()
| Имя месяца |
NOW()
| Возвратит текущую дату и время |
PERIOD_ADD() | Добавляет период к году и месяцу |
PERIOD_DIFF() | Возвратит число месяцев между периодами |
QUARTER()
| Квартал из значения date |
SEC_TO_TIME() | Конвертирует секунды в формат 'HH:MM:SS'
|
SECOND()
| Возвратит секунды (0-59) |
STR_TO_DATE() | Конвертирует строку в дату |
SUBDATE()
| Синоним для DATE_SUB(), когда вызвана с тремя параметрами
|
SUBTIME()
| Вычитает время |
SYSDATE()
| Время выполнения функции |
TIME()
| Извлекает часть времени из выражения |
TIME_FORMAT() | Форматирует время |
TIME_TO_SEC() |
Возвратит параметр, преобразованный в секунды |
TIMEDIFF()
| Вычитает время |
TIMESTAMP()
| С единственным параметром эта функция возвращает дату или
выражение datetime, с двумя параметрами, их сумму |
TIMESTAMPADD() | Добавляет интервал к datetime |
TIMESTAMPDIFF() | Вычитает интервал из datetime |
TO_DAYS()
| Возвратит параметр даты, преобразованный в дни |
TO_SECONDS() | Возвратит параметр даты или datetime,
преобразованный в секунды с года 0 |
UNIX_TIMESTAMP() | Unix timestamp |
UTC_DATE()
| Текущая дата в UTC |
UTC_TIME()
| Текущее время в UTC |
UTC_TIMESTAMP() | Текущие дата и время в UTC |
WEEK()
| Номер недели |
WEEKDAY()
| Индекс дня недели |
WEEKOFYEAR() | Календарная неделя для даты (1-53) |
YEAR()
| Год |
YEARWEEK()
| Год и неделя |
Вот пример, который использует функции даты. Следующий запрос выбирает все
строки с date_col в пределах прошлых 30 дней:
mysql> SELECT something FROM tbl_name
-> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col ;
Запрос также выбирает строки с датами, которые лежат в будущем.
Функции, которые ожидают значения даты, обычно принимают значения datetime
и игнорируют часть времени. Функции, которые ожидают временные значения,
обычно принимают значения datetime и игнорируют часть даты.
Функции, которые возвращают текущую дату или время, оцениваются
только однажды в начале выполнения запроса. Это означает, что многократные
ссылки на функцию такие, как NOW()
в пределах единственного запроса всегда приводят к тому же самому
результату. В наших целях единственный запрос также включает вызов
сохраненной программы и всех подпрограмм, вызванных той программой.
Этот принцип также относится к
CURDATE() ,
CURTIME() ,
UTC_DATE() ,
UTC_TIME() ,
UTC_TIMESTAMP()
и к любому из их синонимов.
CURRENT_TIMESTAMP()
,
CURRENT_TIME() ,
CURRENT_DATE() и
FROM_UNIXTIME()
возвращают значения функций в зоне текущего времени соединения, которая
доступна как значение системной переменной
time_zone .
Кроме того,
UNIX_TIMESTAMP() предполагает, что параметр значение datetime в
зоне текущего времени. См.
раздел 11.6.
Некоторые функции даты могут использоваться с
нулевыми или неполными датами, например, '2001-11-00'
, тогда как другие не могут. Функции, которые извлекают части дат,
как правило, работают с неполными датами и таким образом могут возвратить 0,
когда Вы могли бы ожидать ненулевое значение. Например:
mysql> SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
-> 0, 0
Другие функции ожидают полные даты и возвращают
NULL для неполных дат. Они включают функции, которые выполняют
арифметику даты или отображают части дат к именам. Например:
mysql> SELECT DATE_ADD('2006-05-00',INTERVAL 1 DAY);
-> NULL
mysql> SELECT DAYNAME('2006-05-00');
-> NULL
Несколько функций более строги, когда передано значение
DATE()
как их параметр и отклонят неполные даты с дневной частью 0. Эти функции:
CONVERT_TZ() ,
DATE_ADD() ,
DATE_SUB() ,
DAYOFYEAR() ,
LAST_DAY()
(разрешает дневную часть 0),
TIMESTAMPDIFF() ,
TO_DAYS() ,
TO_SECONDS() ,
WEEK() ,
WEEKDAY() ,
WEEKOFYEAR() ,
YEARWEEK() .
Дробные секунды для TIME ,
DATETIME и TIMESTAMP поддержаны до точности
микросекунды. Функции, которые берут временные параметры, принимают значения
с дробными секундами. Возвращаемые значения от временных функций
включают дробные секунды.
ADDDATE(date
, INTERVALexpr
unit ) ,
ADDDATE(expr
, days )
Когда вызвано с формой INTERVAL второго параметра,
ADDDATE()
синоним для DATE_ADD()
. Связанная функция SUBDATE()
синоним для
DATE_SUB() . Для информации о параметре
INTERVAL unit см. функцию
DATE_ADD() .
mysql> SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);
-> '2008-02-02'
mysql> SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
-> '2008-02-02'
Когда вызвано с формой days второго параметра, MySQL
обрабатывает это как целое число дней, которые будут добавлены к
expr .
mysql> SELECT ADDDATE('2008-01-02', 31);
-> '2008-02-02'
ADDTIME(expr1
,expr2 )
ADDTIME() добавляет
expr2 к expr1 и возвращает
результат. expr1 выражение time или datetime, а
expr2 выражение time.
mysql> SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');
-> '2008-01-02 01:01:01.000001'
mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
-> '03:00:01.999997'
CONVERT_TZ(dt
, from_tz ,to_tz )
CONVERT_TZ()
конвертирует значение datetime dt из часового пояса,
данного from_tz к часовому поясу, данному
to_tz и возвращает получающееся значение. Часовые пояса
определены как описано в разделе 11.6
. Эта функция возвращает NULL , если параметры недопустимы.
Если значение выходит из поддержанного диапазона
TIMESTAMP , когда преобразовано
из from_tz в UTC, не происходит никакого
преобразования. Диапазон TIMESTAMP
описан в разделе 12.1.2
.
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-> '2004-01-01 22:00:00'
Чтобы использовать названный часовыми пояс, например, 'MET'
или 'Europe/Moscow' , таблицы часового пояса должны быть должным
образом настроены. См. раздел 11.6
.
CURDATE()
Возвращает текущую дату как значение в формате
'YYYY-MM-DD' или YYYYMMDD , в зависимости от того,
используется ли функция в строковом или числовом контексте.
mysql> SELECT CURDATE();
-> '2008-06-13'
mysql> SELECT CURDATE() + 0;
-> 20080613
CURRENT_DATE ,
CURRENT_DATE()
CURRENT_DATE и
CURRENT_DATE()
синонимы для CURDATE() .
CURRENT_TIME ,
CURRENT_TIME([fsp
])
CURRENT_TIME и
CURRENT_TIME()
синонимы для CURTIME() .
CURRENT_TIMESTAMP
,
CURRENT_TIMESTAMP([fsp ])
CURRENT_TIMESTAMP
и
CURRENT_TIMESTAMP() синонимы для
NOW() .
CURTIME([fsp
])
Возвращает текущее время как значение в формате
'HH:MM:SS' или HHMMSS , в зависимости от того,
используется ли функция в строковом или числовом контексте. Значение выражено
в зоне текущего времени.
Если параметр fsp дан, чтобы определить дробную
точность секунд от 0 до 6, возвращаемое значение включает
дробную часть секунд.
mysql> SELECT CURTIME();
-> '23:50:26'
mysql> SELECT CURTIME() + 0;
-> 235026.000000
DATE(expr )
Извлекает часть даты из выражения expr типа
date или datetime.
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
DATEDIFF(expr1
,expr2 )
DATEDIFF()
возвращает expr1 - expr2 ,
выраженное как значение в днях от одной даты до другой.
expr1 и expr2 выражения
дата или "дата и время". Только части даты
значений используются в вычислении.
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
-> 1
mysql> SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
-> -31
DATE_ADD(date
, INTERVAL expr unit )
, DATE_SUB(date
, INTERVAL expr unit )
Эти функции выполняют арифметику даты. Параметр
date определяет стартовую дату или значение datetime.
expr выражение, определяющее значение интервала,
которое будет добавлено или вычтено из даты. expr
строка, она может начинаться с -
для отрицательных интервалов. unit
ключевое слово, указывающее на величину, в которой
должно интерпретироваться выражение.
Ключевое слово INTERVAL и спецификатор
unit не является чувствительными к регистру.
Следующая таблица показывает ожидаемую форму параметра
expr для каждого значения unit .
Значение unit |
Ожидаемый формат expr |
MICROSECOND |
MICROSECONDS |
SECOND | SECONDS |
MINUTE | MINUTES |
HOUR | HOURS |
DAY | DAYS |
WEEK | WEEKS |
MONTH | MONTHS |
QUARTER | QUARTERS |
YEAR | YEARS |
SECOND_MICROSECOND |
'SECONDS.MICROSECONDS' |
MINUTE_MICROSECOND |
'MINUTES:SECONDS.MICROSECONDS' |
MINUTE_SECOND |
'MINUTES:SECONDS' |
HOUR_MICROSECOND |
'HOURS:MINUTES:SECONDS.MICROSECONDS' |
HOUR_SECOND |
'HOURS:MINUTES:SECONDS' |
HOUR_MINUTE | 'HOURS:MINUTES'
|
DAY_MICROSECOND |
'DAYS HOURS:MINUTES:SECONDS.MICROSECONDS' |
DAY_SECOND |
'DAYS HOURS:MINUTES:SECONDS' |
DAY_MINUTE |
'DAYS HOURS:MINUTES' |
DAY_HOUR | 'DAYS HOURS'
|
YEAR_MONTH | 'YEARS-MONTHS'
|
Возвращаемое значение зависит от параметров:
DATETIME ,
если первый параметр DATETIME
(или TIMESTAMP ),
или если первый параметр DATE
и значение unit использует
HOURS , MINUTES или SECONDS .
- Строка иначе.
Чтобы гарантировать, что результат будет
DATETIME , Вы можете
использовать CAST() ,
чтобы преобразовать первый параметр в
DATETIME .
MySQL разрешает любой разделитель пунктуации в формате
expr . Показанные в таблице являются предложенными
разделителями. Если параметр date типа
DATE и Ваши вычисления
вовлекают только части YEAR , MONTH и
DAY (без частей времени), результат будет типа
DATE . Иначе типа
DATETIME .
Арифметика даты также может быть выполнена, используя
INTERVAL вместе с оператором
+
- :
date + INTERVAL expr unit
date - INTERVAL expr unit
INTERVAL expr
unit разрешен по обе стороны от оператора
+ , если выражение с другой
стороны значение datetime или дата. Для оператора
- INTERVAL
expr unit
разрешен только на правой стороне, потому что не имеет никакого смысла
вычитать дату или значение datetime из интервала.
mysql> SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '2009-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '2008-12-31';
-> '2009-01-01'
mysql> SELECT '2005-01-01' - INTERVAL 1 SECOND;
-> '2004-12-31 23:59:59'
mysql> SELECT DATE_ADD('2000-12-31 23:59:59',
-> INTERVAL 1 SECOND);
-> '2001-01-01 00:00:00'
mysql> SELECT DATE_ADD('2010-12-31 23:59:59',
-> INTERVAL 1 DAY);
-> '2011-01-01 23:59:59'
mysql> SELECT DATE_ADD('2100-12-31 23:59:59',
-> INTERVAL '1:1' MINUTE_SECOND);
-> '2101-01-01 00:01:00'
mysql> SELECT DATE_SUB('2005-01-01 00:00:00',
-> INTERVAL '1 1:1:1' DAY_SECOND);
-> '2004-12-30 22:58:59'
mysql> SELECT DATE_ADD('1900-01-01 00:00:00',
-> INTERVAL '-1 10' DAY_HOUR);
-> '1899-12-30 14:00:00'
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
-> INTERVAL '1.999999' SECOND_MICROSECOND);
-> '1993-01-01 00:00:01.000001'
Если Вы определяете значение интервала, которое слишком коротко (не
включает все части интервала, которые ожидались бы от
unit ), MySQL предполагает, что Вы не учли крайние левые
части значения интервала. Например, если Вы определяете
unit DAY_SECOND , значение
expr будет иметь дни, часы, минуты и
части секунд. Если Вы определяете значение как '1:10' , MySQL
предполагает, что дни и часы отсутствуют, а значение представляет минуты и
секунды. Другими словами, '1:10' DAY_SECOND интерпретируется
таким способом, по которому это эквивалентно
'1:10' MINUTE_SECOND . Это походит на способ, которым MySQL
интерпретирует значения TIME
как представляющие прошедшее время, а не как время суток.
Поскольку expr обработан как строка, надо быть
осторожным, если Вы определяете нестроковое значение с
INTERVAL . Например, со спецификатором интервала
HOUR_MINUTE , 6/4 оценивается как
1.5000 и будет обработано как 1 час 5000 минут:
mysql> SELECT 6/4;
-> 1.5000
mysql> SELECT DATE_ADD('2009-01-01', INTERVAL 6/4 HOUR_MINUTE);
-> '2009-01-04 12:20:00'
Чтобы гарантировать интерпретацию интервала как Вы ожидаете, используйте
CAST() .
Чтобы 6/4 было понято как 1 час 5 минут, приведите это к типу
DECIMAL с
единственной дробной цифрой:
mysql> SELECT CAST(6/4 AS DECIMAL(3,1));
-> 1.5
mysql> SELECT DATE_ADD('1970-01-01 12:00:00',
-> INTERVAL CAST(6/4 AS DECIMAL(3,1)) HOUR_MINUTE);
-> '1970-01-01 13:05:00'
Если Вы добавляете к или вычитаете из даты что-то, что содержит часть
времени, результат автоматически преобразован в значение datetime:
mysql> SELECT DATE_ADD('2013-01-01', INTERVAL 1 DAY);
-> '2013-01-02'
mysql> SELECT DATE_ADD('2013-01-01', INTERVAL 1 HOUR);
-> '2013-01-01 01:00:00'
Если Вы добавляете MONTH ,
YEAR_MONTH или YEAR
и у получающейся даты есть день, который больше, чем максимальный день в
новом месяце, день скорректирован к максимальному дню в новом месяце:
mysql> SELECT DATE_ADD('2009-01-30', INTERVAL 1 MONTH);
-> '2009-02-28'
Операции арифметики даты требуют полных дат и не работают с неполными
датами вроде '2006-07-00' или ужасно уродливыми датами:
mysql> SELECT DATE_ADD('2006-07-00', INTERVAL 1 DAY);
-> NULL
mysql> SELECT '2005-03-32' + INTERVAL 1 MONTH;
-> NULL
DATE_FORMAT(date
,format )
Форматирует значение date согласно строке
format .
Следующие спецификаторы могут использоваться в строке
format . Символ % требуется перед
символами спецификатора формата.
Спецификатор | Описание |
%a |
Сокращенное имя дня (Sun ..Sat ) |
%b | Сокращенное имя месяца
(Jan ..Dec ) |
%c | Месяц, числовое представление
(0 ..12 ) |
%D | День месяца с английским
суффиксом (0th , 1st , 2nd ,
3rd , ...) |
%d | День месяца, числовой вид
(00 ..31 ) |
%e | День месяца, числовой вид
(0 ..31 ) |
%f | Микросекунды
(000000 ..999999 ) |
%H | Час (00 ..23
) |
%h | Час (01 ..12
) |
%I | Час (01 ..12
) |
%i | Минуты, числовой вид
(00 ..59 ) |
%j | День года
(001 ..366 ) |
%k | Час
(0 ..23 ) |
%l | Час
(1 ..12 ) |
%M | Имя месяца
Month name (January ..December ) |
%m | Месяц, числовой вид
(00 ..12 ) |
%p | AM или
PM |
%r | Время, 12-часовой формат
(hh:mm:ss , сопровождаемый AM или PM )
|
%S | Секунды (00 ..
59 ) |
%s | Секунды (00 ..
59 ) |
%T | Время, 24-часовой формат
(hh:mm:ss ) |
%U | Недели (00 ..
53 ), где Sunday первый день недели,
WEEK() режим 0 |
%u | Недели (00 ..
53 ), Monday первый день недели,
WEEK() режим 1 |
%V | Недели (01 ..
53 ), Sunday первый день недели,
WEEK() режим 2,
используется с %X |
%v | Недели (01 ..53
), Monday первый день недели,
WEEK() режим 3, используется с %x |
%W | Имя дня
(Sunday ..Saturday ) |
%w | День недели
(0 =Sunday..6 =Saturday) |
%X | Год для недели, где воскресенье
первый день недели, числовой вид, четыре цифры, применяется с %V
|
%x | Год для недели, где понедельник
первый день недели, числовой вид, четыре цифры, применяется с
%v |
%Y | Год, числовой тип, четыре цифры
|
%y | Год, числовой тип, две цифры |
%% | Символ % |
%x |
x для любого
x не упомянутого выше
|
Диапазоны для спецификаторов месяца и дня начинаются с ноля вследствие
того, что MySQL разрешает хранение неполных дат вроде
'2014-00-00' .
Языком, используемым для имен дня и месяца и сокращений, управляет
значение системной переменной
lc_time_names
(раздел 11.7).
Для %U , %u , %V и %v
см. описание функции WEEK()
для информации о значениях режима. Режим затрагивает нумерацию недели.
DATE_FORMAT()
возвращает строку с набором символов и сопоставлением, данным
character_set_connection и
collation_connection
так, чтобы это могло возвратить имена месяца и дня, содержащие
символы не-ASCII.
mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
-> 'Sunday October 2009'
mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',
-> '%D %y %a %d %m %b %j');
-> '4th 00 Thu 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
-> '%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
-> '00'
DATE_SUB(date
, INTERVAL expr unit )
См. описание для DATE_ADD()
.
DAY(date )
DAY() синоним для
DAYOFMONTH() .
DAYNAME(date
)
Возвращает название дня для date . Языком,
используемым для имени, управляет значение
lc_time_names
(раздел 11.7).
mysql> SELECT DAYNAME('2007-02-03');
-> 'Saturday'
DAYOFMONTH(date
)
Возвращает день месяца для date в диапазоне от
1 до 31 или
0 для дат вроде '0000-00-00' или
'2008-00-00' , в которых есть часть нулевого дня.
mysql> SELECT DAYOFMONTH('2007-02-03');
-> 3
DAYOFWEEK(date
)
Возвращается индекс дня date
(1 = Sunday, 2 = Monday,
..., 7 = Saturday). Значения соответствуют стандарту ODBC.
mysql> SELECT DAYOFWEEK('2007-02-03');
-> 7
DAYOFYEAR(date
)
Возвращает день года для date в диапазоне от
1 до 366 .
mysql> SELECT DAYOFYEAR('2007-02-03');
-> 34
EXTRACT(unit
FROM date )
Функция EXTRACT()
использует те же самые виды спецификаторов, что и
DATE_ADD() или
DATE_SUB() , но
извлекает части из даты.
mysql> SELECT EXTRACT(YEAR FROM '2009-07-02');
-> 2009
mysql> SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03');
-> 200907
mysql> SELECT EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03');
-> 20102
mysql> SELECT EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123');
-> 123
FROM_DAYS(N
)
Учитывая номер дня N , вернет значение
DATE .
mysql> SELECT FROM_DAYS(730669);
-> '2007-07-03'
Используйте FROM_DAYS()
с осторожностью для старых дат. Это не предназначено для
использования со значениями, которые предшествуют появлению Григорианского
календаря (1582 г.). См.
раздел 13.8.
FROM_UNIXTIME(
unix_timestamp ) ,
FROM_UNIXTIME(
unix_timestamp ,format )
Возвращает представление unix_timestamp
как значение в виде in 'YYYY-MM-DD HH:MM:SS' или
YYYYMMDDHHMMSS в зависимости от того, используется ли функция в
строковом или числовом контексте. Значение выражено в зоне текущего времени.
unix_timestamp внутреннее значение, которое произведено
функцией UNIX_TIMESTAMP()
.
Если задан format , результат отформатирован согласно
строке format , которая используется как в функции
DATE_FORMAT() .
mysql> SELECT FROM_UNIXTIME(1447430881);
-> '2015-11-13 10:08:01'
mysql> SELECT FROM_UNIXTIME(1447430881) + 0;
-> 20151113100801
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');
-> '2015 13th November 10:08:01 2015'
Отметьте: Если Вы используете
UNIX_TIMESTAMP()
и FROM_UNIXTIME()
, чтобы преобразовать между значениями
TIMESTAMP и Unix timestamp, преобразование будет с потерями,
потому что отображение не является непосредственным в обоих направлениях.
Для деталей см. описание
UNIX_TIMESTAMP() .
GET_FORMAT({DATE|TIME|DATETIME},
{'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})
Возвращает строку формата. Эта функция полезна в комбинации с функциями
DATE_FORMAT() и
STR_TO_DATE() .
Возможные значения для первого и второго параметров в нескольких возможных
строках формата (для используемых спецификаторов см. таблицу в описании
функции DATE_FORMAT()
). Формат ISO обращается к ISO 9075, а не ISO 8601.
Вызов функции | Результат |
GET_FORMAT(DATE,'USA') | '%m.%d.%Y' |
GET_FORMAT(DATE,'JIS') | '%Y-%m-%d' |
GET_FORMAT(DATE,'ISO') | '%Y-%m-%d' |
GET_FORMAT(DATE,'EUR') | '%d.%m.%Y' |
GET_FORMAT(DATE,'INTERNAL') | '%Y%m%d' |
GET_FORMAT(DATETIME,'USA') | '%Y-%m-%d %H.%i.%s'
|
GET_FORMAT(DATETIME,'JIS') | '%Y-%m-%d %H:%i:%s'
|
GET_FORMAT(DATETIME,'ISO') | '%Y-%m-%d %H:%i:%s'
|
GET_FORMAT(DATETIME,'EUR') | '%Y-%m-%d %H.%i.%s'
|
GET_FORMAT(DATETIME,'INTERNAL') | '%Y%m%d%H%i%s'
|
GET_FORMAT(TIME,'USA') | '%h:%i:%s %p' |
GET_FORMAT(TIME,'JIS') | '%H:%i:%s' |
GET_FORMAT(TIME,'ISO') | '%H:%i:%s' |
GET_FORMAT(TIME,'EUR') | '%H.%i.%s' |
GET_FORMAT(TIME,'INTERNAL') | '%H%i%s' |
TIMESTAMP
может также использоваться в качестве первого параметра
GET_FORMAT() ,
когда функция возвращает те же самые значения, что
DATETIME .
mysql> SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
-> '03.10.2003'
mysql> SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
-> '2003-10-31'
HOUR(time )
Возвращает час для time . Диапазон возвращаемого
значения от 0 до 23 для значений времени суток.
Однако, диапазон значений TIME
фактически намного больше, таким образом, HOUR
может возвращать значения больше, чем 23 .
mysql> SELECT HOUR('10:05:03');
-> 10
mysql> SELECT HOUR('272:59:59');
-> 272
LAST_DAY(date
)
Берет дату или значение datetime и возвращает соответствующее значение
для последнего дня месяца. Возвращает NULL ,
если параметр недопустим.
mysql> SELECT LAST_DAY('2003-02-05');
-> '2003-02-28'
mysql> SELECT LAST_DAY('2004-02-05');
-> '2004-02-29'
mysql> SELECT LAST_DAY('2004-01-01 01:01:01');
-> '2004-01-31'
mysql> SELECT LAST_DAY('2003-03-32');
-> NULL
LOCALTIME ,
LOCALTIME([fsp
])
LOCALTIME и
LOCALTIME() синонимы
для NOW() .
LOCALTIMESTAMP ,
LOCALTIMESTAMP([
fsp ])
LOCALTIMESTAMP
и LOCALTIMESTAMP()
синонимы для NOW()
.
MAKEDATE(year
,dayofyear )
Возвращает дату, данную значениями года и дня года.
dayofyear должно быть больше 0,
или результат NULL .
mysql> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);
-> '2011-01-31', '2011-02-01'
mysql> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);
-> '2011-12-31', '2014-12-31'
mysql> SELECT MAKEDATE(2011,0);
-> NULL
MAKETIME(hour
,minute ,second )
Возвращает время, вычисленное из параметров
hour , minute и
second . У параметра second может
быть дробная часть.
mysql> SELECT MAKETIME(12,15,30);
-> '12:15:30'
MICROSECOND(expr
)
Возвращает микросекунды из выражения time или datetime
expr как число в диапазоне от
0 до 999999 .
mysql> SELECT MICROSECOND('12:00:00.123456');
-> 123456
mysql> SELECT MICROSECOND('2009-12-31 23:59:59.000010');
-> 10
MINUTE(time )
Возвращает минуту для time в диапазоне от
0 до 59 .
mysql> SELECT MINUTE('2008-02-03 10:05:03');
-> 5
MONTH(date )
Возвращает месяц для date в диапазоне от
1 до 12 или 0 для дат вроде
'0000-00-00' или '2008-00-00' с
нулевым значением месяца.
mysql> SELECT MONTH('2008-02-03');
-> 2
MONTHNAME(date
)
Возвращает полное имя месяца для
date . Языком, используемым для имени, управляет
значение lc_time_names
(раздел 11.7).
mysql> SELECT MONTHNAME('2008-02-03');
-> 'February'
NOW([fsp ])
Возвращает текущую дату и время как значение в формате
'YYYY-MM-DD HH:MM:SS' или YYYYMMDDHHMMSS
в зависимости от того, используется ли функция в строковом или числовом
контексте. Значение выражено в зоне текущего времени.
Если параметр fsp дан, чтобы определить дробную
точность секунд от 0 до 6, возвращаемое значение включает
дробную часть секунд.
mysql> SELECT NOW();
-> '2007-12-15 23:50:26'
mysql> SELECT NOW() + 0;
-> 20071215235026.000000
NOW()
возвращает постоянное время, которое указывает время, в которое запрос
начал выполняться. В пределах сохраненной функции или триггера
NOW()
возвращает время, в которое функция или запрос вызова начали выполняться.
Это отличается от поведения для
SYSDATE() ,
который возвращает точное время, в которое выполняется.
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
Кроме того, SET TIMESTAMP затрагивает значение, возвращенное
NOW() , но не
SYSDATE() .
Это означает, что настройки timestamp в двоичном журнале не имеют никакого
эффекта на вызовы SYSDATE()
. Установка timestamp к ненулевому значению предписывает каждому
последующему вызову NOW()
возвратить то значение. Установка timestamp к нулю отменяет этот эффект,
чтобы NOW()
возвращал текущую дату и время.
PERIOD_ADD(P
,N )
Добавляет N месяцев к периоду
P (в формате YYMM или
YYYYMM ). Возвращает значение в формате YYYYMM .
Отметьте что параметр периода P
не значение date.
mysql> SELECT PERIOD_ADD(200801,2);
-> 200803
PERIOD_DIFF(P1
,P2 )
Возвращает число месяцев между периодами
P1 и P2 . P1
и P2 должны быть в формате YYMM или
YYYYMM . Отметьте, что параметры периода P1
и P2 не значения date.
mysql> SELECT PERIOD_DIFF(200802,200703);
-> 11
QUARTER(date
)
Возвращает четверть (квартал) года для
date в диапазоне от
1 до 4 .
mysql> SELECT QUARTER('2008-04-01');
-> 2
SECOND(time )
Возвращает секунды для time в диапазоне от
0 до 59 .
mysql> SELECT SECOND('10:05:03');
-> 3
SEC_TO_TIME(seconds
)
Возвращает параметр seconds , преобразованный в часы,
минуты и секунды, как значение
TIME .
Диапазон результата ограничен диапазоном типа
TIME . Предупреждение происходит,
если параметр соответствует значению вне этого диапазона.
mysql> SELECT SEC_TO_TIME(2378);
-> '00:39:38'
mysql> SELECT SEC_TO_TIME(2378) + 0;
-> 3938
STR_TO_DATE(str
,format )
Это инверсия функции
DATE_FORMAT() .
Это берет строку str и строку формата
format .
STR_TO_DATE()
возвращает значение DATETIME ,
если строка формата содержит части даты и времени, значения
DATE или
TIME , если строка содержит только
части даты или времени. Если значение date, time или datetime, извлеченное из
str неправильно,
STR_TO_DATE()
вернет NULL и произведет предупреждение.
Сервер сканирует str и пытается соответствовать
format . Строка формата может содержать буквальные
символы и спецификаторы, начинающиеся с % .
Буквальные символы в format
должны соответствовать буквально str . Спецификаторы
формата в format должны соответствовать части даты или
времени в str . Для спецификаторов, которые могут
использоваться в format , см. описание функции
DATE_FORMAT() .
mysql> SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');
-> '2013-05-01'
mysql> SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');
-> '2013-05-01'
Просмотр запускается в начале str и терпит неудачу,
если format не соответствует. Дополнительные символы в
конце str проигнорированы.
mysql> SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');
-> '09:30:17'
mysql> SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');
-> NULL
mysql> SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');
-> '09:30:17'
У неуказанных частей даты или времени есть значение 0, так что не
полностью определенные значения в str приведут к
результату с некоторыми или всеми частями, установленными в 0:
mysql> SELECT STR_TO_DATE('abc','abc');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('9','%m');
-> '0000-09-00'
mysql> SELECT STR_TO_DATE('9','%s');
-> '00:00:09'
Диапазон, проверяющий части значений даты, описан в
разделе 12.3.1. Это означает, например, что
нулевые или даты со значениями части 0 разрешены, если режим SQL
не установлен так, чтобы отвергнуть такие значения.
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
-> '2004-04-31'
Если включен режим SQL
NO_ZERO_DATE или
NO_ZERO_IN_DATE нулевые или частичные даты отвергнуты. В
этом случае STR_TO_DATE()
вернет NULL с предупреждением:
mysql> SET sql_mode = '';
mysql> SELECT STR_TO_DATE('15:35:00', '%H:%i:%s');
+-------------------------------------+
| STR_TO_DATE('15:35:00', '%H:%i:%s') |
+-------------------------------------+
| 15:35:00 |
+-------------------------------------+
mysql> SET sql_mode = 'NO_ZERO_IN_DATE';
mysql> SELECT STR_TO_DATE('15:35:00', '%h:%i:%s');
+-------------------------------------+
| STR_TO_DATE('15:35:00', '%h:%i:%s') |
+-------------------------------------+
| NULL |
+-------------------------------------+
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1411
Message: Incorrect datetime value: '15:35:00' for function str_to_date
Вы не можете использовать формат "%X%V" для конвертации
строки года и недели в дату, потому что комбинация года и недели уникально не
идентифицирует год и месяц, если неделя пересекает границу месяца. Чтобы
преобразовать такое значение в дату, Вы должны также определить день:
mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
-> '2004-10-18'
SUBDATE(date
, INTERVAL expr
unit ) ,
SUBDATE(expr
, days )
Когда вызвано с формой INTERVAL второго параметра,
SUBDATE() синоним для
DATE_SUB() .
mysql> SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);
-> '2007-12-02'
mysql> SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
-> '2007-12-02'
Вторая форма включает использование целочисленного значения для
days . В таких случаях это интерпретируется как число
дней, которые будут вычтены из даты или datetime-выражения
expr .
mysql> SELECT SUBDATE('2008-01-02 12:00:00', 31);
-> '2007-12-02 12:00:00'
SUBTIME(expr1
,expr2 )
SUBTIME() вернет
expr1 - expr2
выраженное как значение в том же самом формате, что и
expr1 . expr1 выражение time или
datetime, expr2 выражение time.
mysql> SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');
-> '2007-12-30 22:58:58.999997'
mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
-> '-00:59:59.999999'
SYSDATE([fsp
])
Возвращает текущую дату и время как значение в формате
'YYYY-MM-DD HH:MM:SS' или YYYYMMDDHHMMSS
в зависимости от того, используется ли функция в строковом
или числовом контексте.
Если параметр fsp
задан, чтобы определить дробную точность секунд от 0 до 6, возвращаемое
значение включает дробную часть секунд.
SYSDATE()
возвращает время, в которое выполняется. Это отличается от поведения для
NOW() ,
который возвращает постоянное время, которое указывает на время, в которое
запрос начал выполняться. В пределах сохраненной функции или триггера
NOW()
возвращает время, в которое функция или триггер начали выполняться.
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
Кроме того, SET TIMESTAMP затрагивает значение, возвращенное
NOW() , но не
SYSDATE() .
Это означает, что настройки timestamp в двоичном журнале не имеют никакого
эффекта на SYSDATE() .
Поскольку SYSDATE()
может возвратить различные значения даже в пределах того же самого запроса и
не затронут SET TIMESTAMP , это недетерминировано и поэтому
опасно для репликации, если используется основанное на запросах двоичное
журналирование. Если это проблема, Вы можете использовать основанное
на строке журналирование.
Альтернативно, Вы можете использовать опцию
--sysdate-is-now
, чтобы вызвать
SYSDATE()
как псевдоним для
NOW() . Это работает, если
опция используется на ведущем и на ведомом устройствах.
Недетерминированная природа
SYSDATE()
также означает, что индекс не может использоваться для того, чтобы оценить
выражения, которые обращаются к нему.
TIME(expr )
Извлекает часть времени из выражения expr типа time
или datetime и возвращает это как строку. Эта функция опасна для основанной
на запросах репликации. Предупреждение зарегистрировано, если Вы используете
эту функцию, когда
binlog_format установлена в STATEMENT .
mysql> SELECT TIME('2003-12-31 01:02:03');
-> '01:02:03'
mysql> SELECT TIME('2003-12-31 01:02:03.000123');
-> '01:02:03.000123'
TIMEDIFF(expr1
,expr2 )
TIMEDIFF() вернет
expr1 - expr2 как значение time.
expr1 и expr2 выражения типа
time или date-and-time, но оба должны иметь тот же самый тип.
Результат, возвращенный TIMEDIFF() ограничен учтенным
диапазоном TIME .
Альтернативно, Вы можете использовать любую из функций
TIMESTAMPDIFF()
и UNIX_TIMESTAMP()
, они обе возвращают целые числа.
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00',
-> '2000:01:01 00:00:00.000001');
-> '-00:00:00.000001'
mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001',
-> '2008-12-30 01:01:01.000002');
-> '46:58:57.999999'
TIMESTAMP(expr
) ,
TIMESTAMP(expr1
,expr2 )
С единственным параметром эта функция возвращает выражение
expr как значение datetime. С двумя параметрами это
добавляет выражение времени expr2 к
expr1 и возвращает результат как значение datetime.
mysql> SELECT TIMESTAMP('2003-12-31');
-> '2003-12-31 00:00:00'
mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
-> '2004-01-01 00:00:00'
TIMESTAMPADD(unit
,interval ,datetime_expr
)
Добавляет выражение целого числа
interval к date или datetime
datetime_expr . Модуль для
interval дан параметром unit ,
который должен быть одним из следующих значений:
MICROSECOND , SECOND , MINUTE ,
HOUR , DAY , WEEK , MONTH ,
QUARTER или YEAR .
Значение unit может быть определено, используя одно
из ключевых слов как показано, или с приставкой SQL_TSI_ .
Например, DAY и SQL_TSI_DAY оба допустимы.
mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
-> '2003-01-02 00:01:00'
mysql> SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
-> '2003-01-09'
TIMESTAMPDIFF(unit
,datetime_expr1 ,datetime_expr2
)
Вернет datetime_expr2 - datetime_expr1
, где datetime_expr1 и
datetime_expr2 выражения date или datetime.
Одно выражение может быть датой, другое datetime, значение даты обработано
как datetime с частью времени '00:00:00' где необходимо. Модуль
для результата (целое число) дан параметром unit .
Допустимые значения для unit перечислены в описании
TIMESTAMPADD() .
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
-> 3
mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
-> -1
mysql> SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
-> 128885
Порядок параметров date или datetime в этой функции противоположность
используемого с TIMESTAMP()
, когда она вызвана с 2 параметрами.
TIME_FORMAT(time
,format )
Это используется как функция
DATE_FORMAT() ,
но строка format может содержать спецификаторы формата
только для часов, минут, секунд и микросекунд. Другие спецификаторы
производят NULL или 0 .
Если time содержит часть часа, которая больше, чем
23 , спецификаторы формата часа %H и %k
производят значение, больше чем обычный диапазон
0..23 . Другие спецификаторы формата часа производят значение
часа не более 12.
mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
-> '100 100 04 04 4'
TIME_TO_SEC(time
)
Вернет параметр time , конвертированный в секунды.
mysql> SELECT TIME_TO_SEC('22:23:00');
-> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
-> 2378
TO_DAYS(date
)
Учитывая дату date , возвращает
число дней с года 0.
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('2007-10-07');
-> 733321
TO_DAYS()
не предназначен для использования со значениями, которые предшествуют
появлению Григорианского календаря (1582 г.), потому что это не принимает во
внимание дни, которые были потеряны, когда календарь был изменен. Для дат до
1582 г. (и возможно более поздних в других местах действия), следствия этой
функции ненадежны. См. раздел 13.8.
Помните, что MySQL преобразовывает значения года с двумя цифрами в датах к
форме с четырьмя цифрами, используя правила в
разделе 12.3.
Например, '2008-10-07' и '08-10-07'
обработаны как идентичные даты:
mysql> SELECT TO_DAYS('2008-10-07'), TO_DAYS('08-10-07');
-> 733687, 733687
В MySQL нулевая дата определена как '0000-00-00' , даже при
том, что эту дату самостоятельно считают недопустимой. Это означает что, для
'0000-00-00' и '0000-01-01'
TO_DAYS()
возвращает значения, показанные здесь:
mysql> SELECT TO_DAYS('0000-00-00');
+-----------------------+
| to_days('0000-00-00') |
+-----------------------+
| NULL |
+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT TO_DAYS('0000-01-01');
+-----------------------+
| to_days('0000-01-01') |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
Это верно независимо от режима SQL
ALLOW_INVALID_DATES
.
TO_SECONDS(expr
)
Учитывая дату или datetime expr , возвращает число
секунд с года 0. Если expr не допустимая дата или
значение datetime, возвращет NULL .
mysql> SELECT TO_SECONDS(950501);
-> 62966505600
mysql> SELECT TO_SECONDS('2009-11-29');
-> 63426672000
mysql> SELECT TO_SECONDS('2009-11-29 13:43:32');
-> 63426721412
mysql> SELECT TO_SECONDS( NOW() );
-> 63426721458
Подобно TO_DAYS() ,
TO_SECONDS() не предназначен для использования со значениями,
которые предшествуют появлению Григорианского календаря (1582), потому что
это не принимает во внимание дни, которые были потеряны, когда календарь был
изменен. Для дат до 1582 (и возможно более поздний год в других местах),
следствия этой функции ненадежны. См.
раздел 13.8.
Подобно TO_DAYS() ,
TO_SECONDS() преобразовывает значения года с двумя цифрами в
датах к форме с четырьмя цифрами, используя правила в
разделе 12.3.
В MySQL нулевая дата определена как '0000-00-00' , даже при
том, что эту дату самостоятельно считают недопустимой. Это означает, что для
'0000-00-00' и '0000-01-01'
TO_SECONDS()
возвращает такие значения:
mysql> SELECT TO_SECONDS('0000-00-00');
+--------------------------+
| TO_SECONDS('0000-00-00') |
+--------------------------+
| NULL |
+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT TO_SECONDS('0000-01-01');
+--------------------------+
| TO_SECONDS('0000-01-01') |
+--------------------------+
| 86400 |
+--------------------------+
1 row in set (0.00 sec)
Это верно независимо от режима SQL
ALLOW_INVALID_DATES
.
UNIX_TIMESTAMP()
, UNIX_TIMESTAMP(
date )
Если вызвано без параметра, возвращает Unix timestamp (секунды с
'1970-01-01 00:00:00' UTC). Возвращаемое значение целое число,
если никакой параметр не дан или параметр не включает дробную часть секунд,
или DECIMAL ,
если параметр включает дробную часть секунд.
Если UNIX_TIMESTAMP()
вызвана с параметром date ,
это возвращает значение параметра как секунды с
'1970-01-01 00:00:00' UTC. date может
быть строкой DATE ,
DATETIME ,
TIMESTAMP или числом в формате
YYMMDD или YYYYMMDD , произвольно включая дробную
часть секунд. Сервер интерпретирует date
как значение в зоне текущего времени и преобразует это к внутреннему значению
в UTC. Клиенты могут установить свой часовой пояс как описано в
разделе 11.6.
mysql> SELECT UNIX_TIMESTAMP();
-> 1447431666
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19');
-> 1447431619
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');
-> 1447431619.012
Когда UNIX_TIMESTAMP()
используется на столбце
TIMESTAMP , функция возвращает внутреннее значение timestamp
непосредственно, без неявного преобразования string-to-Unix-timestamp
. Если Вы передаете дату не из диапазона
UNIX_TIMESTAMP()
, это возвращает 0 .
Отметьте: Если Вы используете
UNIX_TIMESTAMP()
и FROM_UNIXTIME()
, чтобы преобразовать между значениями
TIMESTAMP и Unix timestamp, преобразование будет с потерями,
потому что отображение не является непосредственным в обоих направлениях.
Например, из-за соглашений для изменений зоны местного времени, возможно
отобразить два значения
UNIX_TIMESTAMP()
на два TIMESTAMP с одним и тем
же временем. FROM_UNIXTIME()
отобразит значение назад только на одно из оригинальных значений
TIMESTAMP .
Вот пример, использования значений
TIMESTAMP
в часовом поясе CET :
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 03:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 02:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
mysql> SELECT FROM_UNIXTIME(1111885200);
+---------------------------+
| FROM_UNIXTIME(1111885200) |
+---------------------------+
| 2005-03-27 03:00:00 |
+---------------------------+
UTC_DATE ,
UTC_DATE()
Возвращает текущую дату UTC как значение в формате
'YYYY-MM-DD' или YYYYMMDD в зависимости от того,
используется ли функция в строковом или числовом контексте.
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
-> '2003-08-14', 20030814
UTC_TIME ,
UTC_TIME([fsp
])
Возвращает текущее время UTC как значение в формате
'HH:MM:SS' или HHMMSS в зависимости от того,
используется ли функция в строковом или числовом контексте.
Если параметр fsp задан, чтобы определить дробную
точность секунд от 0 до 6, возвращаемое значение включает
дробную часть секунд.
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
-> '18:07:53', 180753.000000
UTC_TIMESTAMP ,
UTC_TIMESTAMP([
fsp ])
Возвращает текущую дату UTC и время как значение в формате
'YYYY-MM-DD HH:MM:SS' или YYYYMMDDHHMMSS
в зависимости от того, используется ли функция в строковом
или числовом контексте.
Если параметр fsp задан, чтобы определить дробную
точность секунд от 0 до 6, возвращаемое значение включает
дробную часть секунд.
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
-> '2003-08-14 18:08:04', 20030814180804.000000
WEEK(date [,
mode ])
Эта функция возвращает номер недели для
date . Двухаргументная форма
WEEK()
позволяет Вам определить, запускается ли неделя в воскресенье или в
понедельник и должно ли возвращаемое значение быть в диапазоне от
0 до 53 или от 1 до
53 . Если параметр mode опущен, значение
используется значение из системной переменной
default_week_format . См.
раздел 6.1.5.
Следующая таблица описывает как работает параметр mode
.
Режим | Первый день недели |
Диапазон | Неделя 1 является первой неделей
|
0 | Sunday | 0-53 |
с Sunday в этом году |
1 | Monday | 0-53 |
с 4 или больше днями в этом году |
2 | Sunday | 1-53 |
с Sunday в этом году |
3 | Monday | 1-53 |
с 4 или больше днями в этом году |
4 | Sunday | 0-53 |
с 4 или больше днями в этом году |
5 | Monday | 0-53 |
с Monday в этом году |
6 | Sunday | 1-53 |
с 4 или больше днями в этом году |
7 | Monday | 1-53 |
с Monday в этом году |
Для значений mode со смыслом
"с 4 или больше днями в этом году"
недели пронумерованы согласно ISO 8601:1988.
mysql> SELECT WEEK('2008-02-20');
-> 7
mysql> SELECT WEEK('2008-02-20',0);
-> 7
mysql> SELECT WEEK('2008-02-20',1);
-> 8
mysql> SELECT WEEK('2008-12-31',1);
-> 53
Отметьте что, если дата на прошлой неделе предыдущего года, MySQL
возвращает 0 , если Вы не используете
2 , 3 , 6 или 7
как параметр mode :
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
-> 2000, 0
Можно было бы обсудить, что
WEEK() должна возвратить
52 , потому что данная дата фактически происходит на 52-ой неделе
1999. WEEK() вместо этого
вернет 0 так, чтобы возвращаемое значение было
номером недели в данном году. Это делает функцию
WEEK() надежной, когда
она объединена с другими функциями, которые извлекают часть даты.
Если Вы предпочитаете результат, оцененный относительно года, который
содержит первый день недели для данной даты, надо использовать
0 , 2 , 5 или 7
для параметра mode .
mysql> SELECT WEEK('2000-01-01',2);
-> 52
Альтернативно, используйте функцию
YEARWEEK() :
mysql> SELECT YEARWEEK('2000-01-01');
-> 199952
mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);
-> '52'
WEEKDAY(date
)
Возвращается индекс дня для date
(0 = Monday, 1 = Tuesday, ...,
6 = Sunday).
mysql> SELECT WEEKDAY('2008-02-03 22:23:00');
-> 6
mysql> SELECT WEEKDAY('2007-11-06');
-> 1
WEEKOFYEAR(date
)
Возвращает календарную неделю даты как число в диапазоне от
1 до 53 .
WEEKOFYEAR()
функция совместимости, которая эквивалентна
WEEK(date ,3)
.
mysql> SELECT WEEKOFYEAR('2008-02-20');
-> 8
YEAR(date )
Возвращает год для date в диапазоне
от 1000 до 9999 или
0 для нулевой даты.
mysql> SELECT YEAR('1987-01-01');
-> 1987
YEARWEEK(date
) ,
YEARWEEK(date
,mode )
Год и неделя для даты. Год в результате может отличаться от
года в параметре даты для первой и последней недель года.
Параметр mode работает точно как в функции
WEEK() .
Для синтаксиса единственного параметра используется значение
mode 0. В отличие от
WEEK() , значение
default_week_format
не влияет на
YEARWEEK() .
mysql> SELECT YEARWEEK('1987-01-01');
-> 198652
Отметьте, что номер недели отличается от номера из функции
WEEK()
(0 ) для дополнительных параметров 0 или
1 , поскольку WEEK()
тогда возвращает неделю в контексте данного года.
13.8. Какой календарь использует MySQL?
MySQL использует то, что известно как старый Григорианский календарь
.
Каждая страна, которая переключилась с Юлианского на Григорианский
календарь, должна была отказаться по крайней мере от десяти дней. Чтобы
видеть, как это работает, рассмотрите месяц октября 1582, когда первый
такой переход произошел.
Monday | Tuesday |
Wednesday | Thursday |
Friday | Saturday |
Sunday |
1 | 2 | 3 | 4 | 15 |
16 | 17 |
18 | 19 | 20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 | 28 | 29 |
30 | 31 |
Нет никаких дат между 4 октября и 15 октября. Эту неоднородность называют
cutover. Любые даты перед ней Юлианские, а любые даты после
cutover являются Грегорианскими. Даты во время
cutover являются несуществующими.
Календарь относящийся к датам, когда он не было фактически использован,
назван старым. Таким образом, если мы предполагаем, что никогда
не было cutover, и Грегорианские правила всегда работали, у нас есть старый
Григорианский календарь. Это то, что используется MySQL, как требуется
стандартным SQL. Поэтому даты до cutover, сохраненные как значения MySQL
DATE или
DATETIME
должны быть скорректированы, чтобы дать компенсацию за различие.
Важно понять, что cutover не происходил в то же самое время во всех странах,
и что, чем позже это произошло, тем больше было потеряно дней.
Например, в Великобритании, это имело место в 1752, когда среда 2 сентября
сопровождалась четвергом 14 сентября. Россия оставалась на юлианском
календаре до 1918, теряя 13 дней в процессе, и именно поэтому Октябрьская
революция произошла в ноябре, согласно Григорианскому календарю.
13.9. Функции полнотекстового поиска
MATCH
(col1 ,col2 ,...)
AGAINST (expr
[search_modifier ])
search_modifier:
{IN NATURAL LANGUAGE MODE
| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
| IN BOOLEAN MODE
| WITH QUERY EXPANSION
}
У MySQL есть поддержка полнотекстовой индексации и поиска:
Полнотекстовый поиск выполнен, используя синтаксис
MATCH() ... AGAINST .
MATCH() берет
список разделенных запятой значений, который называет столбцы, которые будут
просмотрены. AGAINST берет строку, чтобы искать и дополнительный
модификатор, который указывает какой поиск использовать. Строка поиска должна
быть строковым значением, которое является постоянным во время оценки
запроса. Это исключает, например, столбец таблицы, потому что это может
отличаться для каждой строки.
Есть три типа полнотекстовых поисков:
Поиск естественного языка интерпретирует строку поиска как фразу
на естественном языке (фраза в свободном тексте). Нет никаких специальных
операторов. Список стоп-слов применяется. Для получения дополнительной
информации о списках стоп-слов см.
раздел 13.9.4.
Полнотекстовые поискы естественного языка, если модификатор дан
IN NATURAL LANGUAGE MODE или если никакой модификатор не дан.
Для получения дополнительной информации см.
раздел 13.9.1.
- Булев поиск интерпретирует строку поиска, используя правила специального
языка запроса. Строка содержит слова для поиска. Это может также содержать
операторы, которые определяют требования, таким образом, что слово должно
присутствовать или отсутствовать в соответствующих строках, или что это
должно иметь больший или меньший вес, чем обычно. Определенные общие слова
(стоп-слов) опущены во время поиска по индексу и не соответствуют, если
существуют в строке поиска. Модификатор
IN BOOLEAN MODE
определяет булев поиск.
- Поиск расширения запроса модификация поиска естественного языка. Строка
поиска используется, чтобы выполнить поиск естественного языка. Тогда слова
самых соответствующих строк, возвращенных поиском, добавлены к строке поиска,
и поиск сделан снова. Запрос возвращает строки из второго поиска. Модификатор
IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION или WITH
QUERY EXPANSION определяет поиск расширения запроса.
myisam_ftdump
выводит содержание полнотекстового индекса MyISAM .
Это может быть полезно для того, чтобы отладить полнотекстовые запросы.
13.9.1.
Полнотекстовые поиски на естественном языке
По умолчанию или с модификатором IN NATURAL LANGUAGE MODE
MATCH() выполняет поиск
естественного языка строки для текстового набора. Набор один или
большее количество столбцов, включенных в индекс FULLTEXT .
Строка поиска дана как параметр AGAINST() . Для каждой строки
в таблице MATCH()
возвращает значение уместности, то есть, мера подобия между строкой поиска и
текстом в строке в столбцах, названных в списке
MATCH() .
mysql> CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT, FULLTEXT (title,body)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
По умолчанию, поиск выполнен нечувствительным к регистру способом. Чтобы
выполнить чувствительный к регистру полнотекстовый поиск, используйте
двоичное сопоставление для индексированных столбцов. Например, столбцу,
который использует набор символов latin1 можно назначить
сопоставление latin1_bin , чтобы сделать это чувствительным к
регистру для полнотекстовых поисков.
Когда MATCH()
используется в WHERE , как в примере, показанном ранее, строки
будут автоматически отсортированы с самой высокой уместностью сначала.
Значения уместности неотрицательные числа с плавающей запятой. Нулевая
уместность не означает подобия. Уместность вычислена основываясь на числе
слов в строке (документе), числе уникальных слов в строке, общем количестве
слов в наборе и числе строк, которые содержат особое слово.
Термин документ может быть использован попеременно с термином
строка, и оба термина относятся к индексированной части строки.
Термин набор относится к индексированным столбцам и
охватывает все строки.
Чтобы просто посчитать соответствия, Вы можете использовать такой запрос:
mysql> SELECT COUNT(*) FROM articles
WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+----------+
| COUNT(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
Вы могли бы счесть более быстрым переписать запрос следующим образом:
mysql> SELECT COUNT(IF(MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL))
AS count FROM articles;
+-------+
| count |
+-------+
| 2 |
+-------+
1 row in set (0.03 sec)
Первый запрос делает некоторую дополнительную работу (сортирует
результаты по уместности), но также может использовать поиск по индексу,
основанный на WHERE . Индексированный поиск мог бы сделать
первый запрос быстрее, если поиску соответствует немного строк. Второй запрос
выполняет полное сканирование таблицы, которое могло бы быть быстрее, чем
поиск по индексу, если бы критерий поиска присутствовал в большинстве строк.
Для естественного языка полнотекстовые поиска, столбцы, названные в
MATCH()
должны быть теми же самыми столбцами, которые включены в индекс
FULLTEXT . Для предыдущего запроса, отметьте, что столбцы,
названные в MATCH()
(title и body ) те же самые, что и названные в
определении индекса FULLTEXT таблицы article .
Чтобы искать title или body отдельно, Вы создали бы
отдельный индекс FULLTEXT для каждого столбца.
Вы можете также выполнить булев поиск или поиск с расширением запроса. Эти
типы поиска описаны в разделах
13.9.2 и
13.9.3.
Полнотекстовый поиск, который использует индексирование, может назвать
столбцы только единственной таблицы в
MATCH() , потому что
индексирование не может охватить много таблиц. Для таблиц
MyISAM булев поиск может быть сделан в отсутствие индексирования
(хотя более медленно), тогда возможно назвать столбцы разных таблиц.
Предыдущий пример основная иллюстрация, которая показывает, как
использовать MATCH() ,
когда строки возвращены в порядке уменьшающейся уместности. Следующий пример
показывает, как получить значения уместности явно. Возвращенные строки не
упорядочены потому, что SELECT
не включает ни одного WHERE или ORDER BY :
mysql> SELECT id, MATCH (title,body)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS score
FROM articles;
+----+---------------------+
| id | score |
+----+---------------------+
| 1 | 0.22764469683170319 |
| 2 | 0 |
| 3 | 0.22764469683170319 |
| 4 | 0 |
| 5 | 0 |
| 6 | 0 |
+----+---------------------+
6 rows in set (0.00 sec)
Следующий пример более сложен. Запрос возвращает значения уместности, а
также сортирует строки в порядке уменьшающейся уместности.
Чтобы достигчь этого результата, определите
MATCH() дважды:
первый в списке SELECT , второй
в предложении WHERE . Это не вызывает проблем, потому что
оптимизатор MySQL замечает два идентичиных вызова
MATCH()
и вызывает полнотекстовый код поиска только однажды.
mysql> SELECT id, body, MATCH (title,body) AGAINST
('Security implications of running MySQL as root'
IN NATURAL LANGUAGE MODE) AS score
FROM articles WHERE MATCH (title,body) AGAINST
('Security implications of running MySQL as root'
IN NATURAL LANGUAGE MODE);
+----+-------------------------------------+-----------------+
| id | body | score |
+----+-------------------------------------+-----------------+
| 4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
| 6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)
В MySQL FULLTEXT расценивает любую последовательность
истинных символов слова (буквы, цифры и подчеркивания) как слово. Та
последовательность может также содержать апострофы (' ), но не
больше, чем один подряд. Это означает, что aaa'bbb расценено как
одно слово, но aaa''bbb как два. Апострофы в начале или конце
слова игнорируются анализатором в любом количестве:
'aaa'bbb' обрабатывается как aaa'bbb .
Встроенный анализатор FULLTEXT определяет, где слова
начинаются и заканчиваются, ища определенные символы-разделители,
например, (пробел), , (запятая) и .
(точка). Если слова не отделены разделителями (как в, например, китайском
языке), встроенный анализатор FULLTEXT не может определить, где
слово начинается или заканчивается. Чтобы добавить слова или другие
индексированные термины на таких языках к индексу FULLTEXT ,
который использует встроенный анализатор FULLTEXT ,
Вы должны предварительно обработать их так, чтобы они были отделены некоторым
произвольным разделителем, например, " .
Альтернативно, Вы можете создать индексы FULLTEXT ,
используя плагин анализатора ngram (для китайского, японского или корейского
языка) или плагин анализатора MeCab (для японского языка).
Возможно написать плагин, который заменяет встроенный полнотекстовый
анализатор. Для деталей см. раздел 26.2.
Например исходный код плагина анализатора есть в каталоге
plugin/fulltext исходных текстов MySQL.
Некоторые слова проигнорированы в полнотекстовых поисках:
Любое слово, которое слишком коротко, проигнорировано. Длина
минимума значения по умолчанию слов, которые найдены полнотекстовыми
поисками, является тремя символами для InnoDB и четыремя
символами для MyISAM . Вы можете управлять сокращением,
устанавливая параметр конфигурации прежде, чем создать индекс:
параметр конфигурации для InnoDB
innodb_ft_min_token_size или
ft_min_word_len для MyISAM .
Это поведение не относится к индексам
FULLTEXT , которые используют ngram. Для него
маркерная длина определена опцией
ngram_token_size .
Слова в списке стоп-слов проигнорированы. Стоп-слово такое слово, как
the или some, которое настолько распространено, что
у него, как полагают, есть нулевое семантическое значение. Есть встроенный
список стоп-слов, но он может быть перекрыт определяемым пользователем
списком. Списки стоп-слов и связанные параметры конфигурации отличаются для
InnoDB и MyISAM . Обработкой стоп-слов управляют
параметры конфигурации
innodb_ft_enable_stopword ,
innodb_ft_server_stopword_table и
innodb_ft_user_stopword_table для for InnoDB и
ft_stopword_file
для MyISAM .
См. раздел 13.9.4
для значения по умолчанию списка стоп-слов и как изменить их.
Минимум длины слова по умолчанию может быть изменен как описано в
разделе 13.9.6.
Каждое правильное слово в наборе и в запросе взвешено,
согласно его значению в наборе или запросе. Таким образом, у слова, которое
присутствует во многих документах, есть более низкий вес, потому что у него
есть более низкое семантическое значение в этом особом наборе. Наоборот, если
слово редко, оно получает более высокий вес. Веса слов объединены, чтобы
вычислить уместность строки. Этот метод работает лучше всего с
большим количеством слов.
Ограничения MyISAM.
Для очень маленьких таблиц распределение слов не
отражает их семантическое значение, и эта модель может иногда приводить к
причудливым результатам для поиска в таблицах MyISAM .
Например, хотя слово MySQL присутствует в каждой строке
таблицы articles выше, поиск слова в MyISAM
не даст результатов:
mysql> SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('MySQL' IN NATURAL LANGUAGE MODE);
Empty set (0.00 sec)
Результат поиска пуст, потому что MySQL
присутствует по крайней мере в 50% строк и поэтому эффективно обработано
как стоп-слово. Этот метод фильтрации является более подходящим для больших
наборов данных, где Вы не могли бы хотеть, чтобы набор результатов возвратил
каждую вторую строку из таблицы в 1GB, чем для маленьких наборов данных, где
это могло бы вызвать маленькие результаты для популярных слов.
50% порог может удивить Вас, когда Вы сначала пробуете полнотекстовый
поиск, чтобы видеть, как это работает, и делает таблицы InnoDB
более подходящими для экспериментирования с полнотекстовыми поисками. Если Вы
создаете таблицу MyISAM и вставляете только одну или две строки
текста в нее, каждое слово в тексте будет по крайней мере в 50% строк.
В результате никакой поиск не возвращает результатов, пока таблица не
содержит больше строк. Пользователи, которые должны обойти 50% ограничение,
могут создать поисковые индексы на таблицах InnoDB
или использовать булев режим поиска, объясненный в
разделе 13.9.2.
13.9.2. Булев полнотекстовый поиск
MySQL может выполнить булев полнотекстовый поиск, используя
модификатор IN BOOLEAN MODE . С этим модификатором у
определенных символов есть особое значение в начале или конце слов в строке
поиска. В следующем запросе операторы + и -
указывают, что слово должно присутствовать или отсутствовать, соответственно,
для соответствия. Таким образом, запрос получает все строки, которые содержат
слово MySQL, но не содержат слово
YourSQL:
mysql> SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+----+-----------------------+-------------------------------------+
| id | title | body |
+----+-----------------------+-------------------------------------+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 2 | How To Use MySQL Well | After you went through a ... |
| 3 | Optimizing MySQL | In this tutorial we will show ... |
| 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... |
| 6 | MySQL Security | When configured properly, MySQL ... |
+----+-----------------------+-------------------------------------+
В реализации этой опции MySQL использует то, что иногда упоминается как
подразумеваемая Булева логика, в которой:
+ означает AND .
- означает NOT .
- [отсутствие оператора] означает
OR .
У булевых полнотекстовых поисков есть эти характеристики:
Они автоматически не сортируют строки в
порядке уменьшающейся уместности.
- Таблицы
InnoDB требуют индекс FULLTEXT
на всех столбцах выражения MATCH()
, чтобы выполнить булевы запросы. Булевы запросы на поисковых
индексах MyISAM могут работать даже без индекса
FULLTEXT , хотя поиск, выполненный этим способом,
был бы довольно медленным.
- Минимальная и максимальная длина слова полнотекстовых параметров
относится к индексам
FULLTEXT , создаваемым с использованием
встроенного анализатора FULLTEXT и плагина анализатора MeCab.
innodb_ft_min_token_size и
innodb_ft_max_token_size используются для поисковых индексов
InnoDB .
ft_min_word_len и
ft_max_word_len используются для поисковых
индексов MyISAM .
Минимальная и максимальная длина слова в параметрах не относится к
индексам FULLTEXT , создаваемым с использованием анализатора
ngram. Маркерный размер ngram определен опцией
ngram_token_size .
- Список стоп-слов применяется, управляемый
innodb_ft_enable_stopword ,
innodb_ft_server_stopword_table
и
innodb_ft_user_stopword_table для InnoDB или
ft_stopword_file
для MyISAM .
- Полнотекстовый поиск
InnoDB не поддерживает использование
нескольких операторов на единственном слове поиска, как в этом примере:
'++apple' . Использование нескольких операторов на единственном
слове поиска возвращает синтаксическую ошибку. Полнотекстовый поиск MyISAM
успешно обработает тот же самый поиск, игнорируя все операторы за исключением
оператора, смежного со словом поиска.
- Полнотекстовый поиск
InnoDB поддерживает только символы
плюс или минус. Например, InnoDB поддерживает
'+apple' , но не 'apple+' .
Определение плюса или минуса в конце приводит к синтаксической ошибке.
- Полнотекстовый поиск
InnoDB не поддерживает использование
ведущего знака плюс с подстановочным знаком ('+*' ) и
комбинацию знак плюс и минус ('+-' ).
Эти недопустимые запросы возвращают синтаксическую ошибку.
- Полнотекстовый поиск
InnoDB не поддерживает
использование символа @ в булевых полнотекстовых поисках.
Символ @ зарезервирован для использования в операторе
поиска близости @distance .
- Они не используют 50% порог, который относится к
поисковым индексам
MyISAM .
Булев полнотекстовый поиск поддерживает следующие операторы:
+
Знак плюс указывают, что это слово
должно присутствовать в каждой строке, которая
возвращена. InnoDB поддерживает только знак плюс в начале.
-
Знак минус указывают, что это слово не должно
присутствовать в каждой строке, которая возвращена.
InnoDB поддерживает только знак плюс в начале.
Отметьте: оператор - действует только, чтобы
исключить строки, которые являются иначе соответствующими другими критериями
поиска. Таким образом, поиск булева режима, который содержит только
термины, которым предшествует - возвращает пустой результат. Это
не возвращает все строки кроме тех, которые содержат любой
из исключенных терминов.
- (no operator)
По умолчанию (когда ни + ни - не заданы),
слово является дополнительным, но строки, которые содержат его, оценены выше.
Это подражает поведению MATCH() ...
AGAINST() без модификатора IN BOOLEAN MODE .
@distance
Этот оператор работает только на таблицах InnoDB .
Это проверяет, начинаются ли два или больше слов в пределах указанного
расстояния друг от друга, измеренного в словах. Определите слова поиска в
двойных кавычках немедленно перед оператором @distance
, например, MATCH(col1) AGAINST('"word1 word2 word3" @8'
IN BOOLEAN MODE) .
> <
Эти два оператора используются, чтобы изменить вклад слова в значение
уместности, которое назначено строке. Оператор > увеличивает
вклад, а < уменьшает.
( )
Слова в круглых скобках группируются в подвыражения. Могут быть вложены.
~
Ведущая тильда действует как оператор отрицания, делая вклад слова в
уместность строки отрицательным. Это полезно для маркировки слов.
Строка, содержащая такое слово, оценена ниже чем другие, но не исключена в
целом, как это было бы с оператором - .
*
Звездочка служит усечением (или подстановочным знаком).
В отличие от других операторов, это добавлено к слову,
которое будет затронуто. Слова соответствуют, если они начинаются
со слова, предшествующего * .
Если слово определено с оператором усечения, он не обрезается от булева
запроса, даже если это слишком коротко или стоп-слово. Слишком короткое
слово, определено в
innodb_ft_min_token_size для InnoDB или
ft_min_word_len
для MyISAM . Эти опции неприменимы к индексам
FULLTEXT , использующим анализатор ngram.
Слово со звездочкой рассматривают как приставку, которая должна
присутствовать в начале одного или более слов. Если минимальная длина слова
4, поиск '+слово +the*'
может возвратить меньше строк, чем поиск
'+слово +the' , потому что второй запрос
игнорирует также короткий критерий поиска the .
"
Фразе, которая указана в пределах двоичной кавычки (" )
соответствуют только строки, которые содержат фразу
как она написана.
Полнотекстовый механизм разделяет фразу на слова и выполняет поиск в индексах
FULLTEXT для всех слов.
Символы, не являющиеся словами, не должны быть соответствующими точно: поиск
фразы требует, чтобы соответствия содержали точно те же самые слова, что и
фраза, и в том же самом порядке. Например, "test phrase"
соответствует "test, phrase" .
Если фраза не содержит слов, которые находятся в индексе, результат пуст.
Слова могут не быть в индексе из-за комбинации факторов: если они не
существуют в тексте, являются стоп-словами или короче, чем минимальная
длина индексированных слов.
Следующие примеры демонстрируют некоторые строки поиска, которые
используют булевы полнотекстовые операторы:
'apple banana'
Найдет строки, которые содержат по крайней мере одно из этих двух слов.
'+apple +juice'
Найдет строки, которые содержат оба слова.
'+apple macintosh'
Найдет строки, которые содержат слово apple, но вес строк
выше, если они также содержат macintosh.
'+apple -macintosh'
Найдет строки, которые содержат слово apple,
но не macintosh.
'+apple ~macintosh'
Найдет строки, которые содержат слово apple, но если строка
также содержит macintosh, ее вес ниже, чем если бы строка его не
включала. Это мягче, чем поиск '+apple -macintosh' ,
для которого присутствие macintosh не вернет строку вообще.
'+apple +(>turnover <strudel)'
Найдет строки, которые содержат слова apple и
turnover, или apple и strudel (в любом
порядке), но вес apple turnover выше, чем apple strudel
.
'apple*'
Найдет строки, которые содержат слова, такие как apple,
apples, applesauce или applet.
'"some words"'
Найдет строки, которые содержат точную фразу some words
(например, строки, которые содержат some words of wisdom, но не
some noise words). Отметьте, что символы "
являются символами оператора, которые разграничивают фразу. Они не кавычки,
которые прилагают строку поиска непосредственно.
Ранжирование уместности для режима InnoDB булева поиска
Полнотекстовый поиск InnoDB
смоделирован на полнотекстовой поисковой системе
Sphinx, используемые
алгоритмы основаны на алгоритма ранжирования
BM25 и
TF-IDF.
По этим причинам, ранжирование уместности для булева полнотекстового поиска
InnoDB может отличаться от ранжирования уместности
MyISAM .
InnoDB использует вариант системы взвешивания term
frequency-inverse document frequency (TF-IDF ), чтобы
оценить уместность документа для данного полнотекстового запроса поиска.
TF-IDF основана на том, как часто слово появляется в документе,
с поправкой на то, как часто слово появляется во всех документах в наборе.
Другими словами, чем более часто слово появляется в документе, и чем менее
часто слово появляется в наборе документа, тем выше документ оценивается.
Как ранжирование уместности вычислено
Значение частоты термина (term frequency, TF )
число раз, которые слово появляется в документе. Обратная частота документа
(IDF ) слова вычислено, используя следующую формулу, где
total_records число записей в наборе, а
matching_records число записей, в которых
появляется критерий поиска.
${IDF} = log10( ${total_records} / ${matching_records} )
Когда документ содержит слово многократно, значение IDF умножено
на значение TF:
${TF} * ${IDF}
Используя значения TF и IDF , уместность
для документа вычислена, используя эту формулу:
${rank} = ${TF} * ${IDF} * ${IDF}
Формула продемонстрирована в следующих примерах.
Уместность для поиска отдельного слова
Этот пример демонстрирует вычисление ранжирования уместности для
поиска изолированного слова.
mysql> CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT, FULLTEXT (title,body)) ENGINE=InnoDB;
Query OK, 0 rows affected (1.04 sec)
mysql> INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','This database tutorial ...'),
("How To Use MySQL",'After you went through a ...'),
('Optimizing Your Database','In this database tutorial ...'),
('MySQL vs. YourSQL','When comparing databases ...'),
('MySQL Security','When configured properly, MySQL ...'),
('Database, Database, Database','database database database'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL Full-Text Indexes', 'MySQL fulltext indexes use a ..');
Query OK, 8 rows affected (0.06 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> SELECT id, title, body, MATCH (title,body)
AGAINST ('database' IN BOOLEAN MODE)
AS score FROM articles ORDER BY score DESC;
+----+------------------------------+-------------------------------------+---------------------+
| id | title | body | score |
+----+------------------------------+-------------------------------------+---------------------+
| 6 | Database, Database, Database | database database database | 1.0886961221694946 |
| 3 | Optimizing Your Database | In this database tutorial ... | 0.36289870738983154 |
| 1 | MySQL Tutorial | This database tutorial ... | 0.18144935369491577 |
| 2 | How To Use MySQL | After you went through a ... | 0 |
| 4 | MySQL vs. YourSQL | When comparing databases ... | 0 |
| 5 | MySQL Security | When configured properly, MySQL ... | 0 |
| 7 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | 0 |
| 8 | MySQL Full-Text Indexes | MySQL fulltext indexes use a .. | 0 |
+----+------------------------------+-------------------------------------+---------------------+
8 rows in set (0.00 sec)
Есть 8 записей всего, с 3, которые соответствуют поисковому термину
database. Первая запись (id 6 ) содержит поисковый
термин 6 раз и имеет ранжирование уместности 1.0886961221694946 .
Это значение ранжирования вычислено, используя значение TF 6
критерий поиска появляется 6 раз в записи id 6 )
и IDF 0.42596873216370745, который вычислен следующим образом
(здесь 8 общее количество записей, 3 число записей, в которых
критерий поиска появляется):
${IDF} = log10( 8 / 3 ) = 0.42596873216370745
Значения TF и IDF тогда вводятся в формулу:
{rank} = ${TF} * ${IDF} * ${IDF}
Выполнение вычисления в клиенте командной строки MySQL возвращает значение
1.088696164686938.
mysql> SELECT 6*log10(8/3)*log10(8/3);
+-------------------------+
| 6*log10(8/3)*log10(8/3) |
+-------------------------+
| 1.088696164686938 |
+-------------------------+
1 row in set (0.00 sec)
Вы можете заметить незначительные различия в значениях, возвращенных
запросом SELECT ... MATCH ... AGAINST и клиентом командной
строки MySQL (1.0886961221694946 и
1.088696164686938 ). Различие происходит из-за проблем округления
между целыми числами и floats/doubles, которое выполнено внутренне
InnoDB (наряду со связанной точностью и округлением решений) и
тем, как оно выполнено в другом месте (в клиенте командной строки MySQL или
других типах вычислителей).
Уместность для поиска нескольких слов
Этот пример демонстрирует вычисление ранжирования уместности для
полнотекстового поиска нескольких слов, основанного на таблице
articles и данных, которые используются в предыдущем примере.
Если Вы ищете больше, чем одно слово, значение ранжирования уместности
сумма значений ранжирования уместности для каждого слова, как
показано в этой формуле:
${rank} = ${TF} * ${IDF} * ${IDF} + ${TF} * ${IDF} * ${IDF}
Выполнение поиска на двух условиях ('mysql tutorial')
возвращает следующие результаты:
mysql> SELECT id, title, body, MATCH (title,body)
AGAINST ('mysql tutorial' IN BOOLEAN MODE)
AS score FROM articles ORDER BY score DESC;
+----+------------------------------+-------------------------------------+----------------------+
| id | title | body | score |
+----+------------------------------+-------------------------------------+----------------------+
| 1 | MySQL Tutorial | This database tutorial ... | 0.7405621409416199 |
| 3 | Optimizing Your Database | In this database tutorial ... | 0.3624762296676636 |
| 5 | MySQL Security | When configured properly, MySQL ... | 0.031219376251101494 |
| 8 | MySQL Full-Text Indexes | MySQL fulltext indexes use a .. | 0.031219376251101494 |
| 2 | How To Use MySQL | After you went through a ... | 0.015609688125550747 |
| 4 | MySQL vs. YourSQL | When comparing databases ... | 0.015609688125550747 |
| 7 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | 0.015609688125550747 |
| 6 | Database, Database, Database | database database database | 0 |
+----+------------------------------+-------------------------------------+----------------------+
8 rows in set (0.00 sec)
В первой записи (id 8 ) 'mysql' появляется однажды, а
'tutorial' два раза. Есть шесть соответствующих записей для 'mysql' и две
для 'tutorial'. Клиент командной строки MySQL возвращает ожидаемое значение
ранжирования, вставляя эти значения в формулу для многократного поиска слова:
mysql> SELECT (1*log10(8/6)*log10(8/6)) + (2*log10(8/2)*log10(8/2));
+-------------------------------------------------------+
| (1*log10(8/6)*log10(8/6)) + (2*log10(8/2)*log10(8/2)) |
+-------------------------------------------------------+
| 0.7405621541938003 |
+-------------------------------------------------------+
1 row in set (0.00 sec)
Незначительные различия в значениях, возвращенных
SELECT ... MATCH ... AGAINST и клиентом командной
строки MySQL объяснены в предыдущем примере.
13.9.3.
Полнотекстовые поиски с расширением запроса
Полнотекстовый поиск поддерживает расширение запроса (и, в частности,
его разновидность blind query expansion).
Это вообще полезно, когда фраза поиска слишком коротка, что часто означает,
что пользователь полагается на подразумеваемое знание, которого
полнотекстовой поисковой системе недостает. Например, пользователь, ищущий
database может действительно подразумевать, что
MySQL, Oracle, DB2,
и RDBMS являются фразами, которые должны соответствовать
databases и должны быть возвращены. Это подразумеваемое знание.
Blind query expansion (также известн, как автоматическая обратная связь
уместности) включен, добавляя WITH QUERY EXPANSION или
IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
после фразы поиска. Это работает, выполняя поиск дважды, поисковая фраза для
второго поиска, это оригинальная фраза поиска, связанная с немногими наиболее
соответствующими документами из первого поиска. Таким образом, если один из
этих документов содержит слова databases и MySQL,
второй поиск находит документы, которые содержат MySQL, даже
если они не содержат database. Следующий пример
показывает это различие:
mysql> SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('database' WITH QUERY EXPANSION);
+----+-----------------------+------------------------------------------+
| id | title | body |
+----+-----------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 3 | Optimizing MySQL | In this tutorial we will show ... |
| 6 | MySQL Security | When configured properly, MySQL ... |
| 2 | How To Use MySQL Well | After you went through a ... |
| 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... |
+----+-----------------------+------------------------------------------+
6 rows in set (0.00 sec)
Другой пример мог искать книги Georges Simenon о Maigret, когда
пользователь не уверен, как писать Maigret. Поиск
Megre and the reluctant witnesses найдет только
Maigret and the Reluctant Witnesses
без расширения запроса. Поиск с расширением запроса считает все книги со
словом Maigret на втором проходе.
Поскольку расширение запроса имеет тенденцию значительно увеличивать шум,
возвращая несоответствующие документы, используйте это только, когда
фраза поиска коротка.
13.9.4. Полнотекстовые стоп-слова
Список стоп-слов загружен и просматривается для полнотекстовых запросов,
используя набор символов сервера и сопоставление (значения переменных
character_set_server
и
collation_server ). Ложные хиты или промахи могли бы произойти
для стоп-слов поисков, если у стоп-слов файла или столбцов, используемых для
полнотекстовой индексации или поисков, есть набор символов или сопоставление,
отличающееся от
character_set_server
или
collation_server .
Чувствительность к регистру стоп-слов поисков зависит от сопоставления
сервера. Например, поиски являются нечувствительными к регистру, если
сопоставление latin1_swedish_ci , тогда как поиски являются
чувствительными к регистру, если сопоставление
latin1_general_cs или latin1_bin .
Стоп-слова для поисковых индексов InnoDB
InnoDB имеет относительно короткий список стоп-слов
по умолчанию, потому что документы из технических, литературных и других
источников часто используют короткие слова в качестве ключевых слов или в
существенных фразах. Например, Вы могли бы искать to be or not
to be и ожидать получения заметного результата, вместо того, чтобы
игнорировать все эти слова.
Чтобы посмотреть список стоп-слов в InnoDB по умолчанию,
запросите таблицу
INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD .
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
+-------+
| value |
+-------+
| a |
| about |
| an |
| are |
| as |
| at |
| be |
| by |
| com |
| de |
| en |
| for |
| from |
| how |
| i |
| in |
| is |
| it |
| la |
| of |
| on |
| or |
| that |
| the |
| this |
| to |
| was |
| what |
| when |
| where |
| who |
| will |
| with |
| und |
| the |
| www |
+-------+
36 rows in set (0.00 sec)
Определить Ваш собственный список стоп-слов для всех таблиц
InnoDB можно, определив таблицу с той же самой структурой, как у
INNODB_FT_DEFAULT_STOPWORD , заполнив ее стоп-словами и установив
значение
innodb_ft_server_stopword_table в форме
db_name /table_name
прежде, чем создать полнотекстовый индекс. У таблицы стоп-слов должен быть
один столбец VARCHAR с именем
value . Следующий пример демонстрирует создание и
конфигурирование новой глобальной таблицы стоп-слов для InnoDB .
-- Create a new stopword table
mysql> CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB;
Query OK, 0 rows affected (0.01 sec)
-- Insert stopwords (for simplicity, a single stopword is used in this example)
mysql> INSERT INTO my_stopwords(value) VALUES ('Ishmael');
Query OK, 1 row affected (0.00 sec)
-- Create the table
mysql> CREATE TABLE opening_lines (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200),
title VARCHAR(200)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
-- Insert data into the table
mysql> INSERT INTO opening_lines(opening_line,author,title) VALUES
('Call me Ishmael.','Herman Melville','Moby-Dick'),
('A screaming comes across the sky.','Thomas Pynchon','Gravity\'s Rainbow'),
('I am an invisible man.','Ralph Ellison','Invisible Man'),
('Where now? Who now? When now?','Samuel Beckett','The Unnamable'),
('It was love at first sight.','Joseph Heller','Catch-22'),
('All this happened, more or less.','Kurt Vonnegut','Slaughterhouse-Five'),
('Mrs. Dalloway said she would buy the flowers herself.','Virginia Woolf','Mrs. Dalloway'),
('It was a pleasure to burn.','Ray Bradbury','Fahrenheit 451');
Query OK, 8 rows affected (0.00 sec)
Records: 8 Duplicates: 0 Warnings: 0
-- Set the innodb_ft_server_stopword_table option to the new stopword table
mysql> SET GLOBAL innodb_ft_server_stopword_table = 'test/my_stopwords';
Query OK, 0 rows affected (0.00 sec)
-- Create the full-text index (which rebuilds the table if no FTS_DOC_ID column is defined)
mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line);
Query OK, 0 rows affected, 1 warning (1.17 sec)
Records: 0 Duplicates: 0 Warnings: 1
Проверьте, что указанное стоп-слово ('Ishmael') не появляется, запрашивая
слова в
INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE .
По умолчанию, слова меньше, чем 3 символа в длину или больше, чем 84
символа не появляются в полнотекстовом индексе InnoDB .
Максимальные и минимальные значения длины слова конфигурируются с применеием
переменных
innodb_ft_max_token_size и
innodb_ft_min_token_size . Это поведение не относится к плагину
анализатора ngram. Маркерный размер ngram определен опцией
ngram_token_size
.
mysql> SET GLOBAL innodb_ft_aux_table='test/opening_lines';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT word FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE LIMIT 15;
+-----------+
| word |
+-----------+
| across |
| all |
| burn |
| buy |
| call |
| comes |
| dalloway |
| first |
| flowers |
| happened |
| herself |
| invisible |
| less |
| love |
| man |
+-----------+
15 rows in set (0.00 sec)
Чтобы создать списки стоп-слов на основе таблицы, составьте другие таблицы
стоп-слов и используйте опцию
innodb_ft_user_stopword_table , чтобы определить таблицу стоп-слов,
которую Вы хотите использовать прежде, чем Вы
создадите полнотекстовый индекс.
Стоп-слова для поиска в MyISAM
Файл загружен стоп-слов загружен с использованием
latin1 , если character_set_server
ucs2 , utf16 ,
utf16le или utf32 .
Чтобы переопределить значение по умолчанию списка стоп-слов для таблиц
MyISAM, установите переменную
ft_stopword_file . См.
раздел 6.1.5.
Значение должно быть путем к файлу, содержащему список стоп-слов, или пустой
строкой, чтобы отключить фильтрацию стоп-слов. Сервер ищет файл в каталоге
данных, если абсолютный путь не дан, чтобы определить иной каталог. После
изменения значения этой переменной или содержания файла стоп-слов,
перезапустите сервер и восстановите Ваши индексы FULLTEXT .
Список стоп-слов имеет свободную форму. Слова разделяются любым знаком
(не буквой и не цифрой). Годятся пробелы, запятые или перевод строки.
Исключения символ подчеркивания (_ ) и единственный апостроф
(' ), которые обработаны как часть слова. Набор символов списка
стоп-слов это набор символов сервера, см.
раздел 11.1.3.2.
Следующая таблица показывает список стоп-слов по умолчанию для
MyISAM . В исходных текстах MySQL он находится в файле
storage/myisam/ft_static.c .
a's | able | about | above |
according |
accordingly | across | actually |
after | afterwards |
again | against | ain't | all |
allow |
allows | almost | alone | along |
already |
also | although | always | am |
among |
amongst | an | and | another |
any |
anybody | anyhow | anyone |
anything | anyway |
anyways | anywhere | apart |
appear | appreciate |
appropriate | are | aren't |
around | as |
aside | ask | asking | associated |
at |
available | away | awfully |
be | became |
because | become | becomes |
becoming | been |
before | beforehand | behind |
being | believe |
below | beside | besides | best |
better |
between | beyond | both | brief |
but |
by | c'mon | c's | came |
can |
can't | cannot | cant | cause |
causes |
certain | certainly | changes |
clearly | co |
com | come | comes | concerning |
consequently |
consider | considering | contain |
containing | contains |
corresponding | could | couldn't |
course | currently |
definitely | described | despite |
did | didn't |
different | do | does | doesn't |
doing |
don't | done | down | downwards |
during |
each | edu | eg | eight |
either |
else | elsewhere | enough |
entirely | especially |
et | etc | even | ever |
every |
everybody | everyone | everything |
everywhere | ex |
exactly | example | except | far |
few |
fifth | first | five | followed |
following |
follows | for | former | formerly |
forth |
four | from | further | furthermore |
get |
gets | getting | given | gives |
go |
goes | going | gone | got |
gotten |
greetings | had | hadn't | happens |
hardly |
has | hasn't | have | haven't |
having |
he | he's | hello | help |
hence |
her | here | here's | hereafter |
hereby |
herein | hereupon | hers | herself |
hi |
him | himself | his | hither |
hopefully |
how | howbeit | however | i'd |
i'll |
i'm | i've | ie | if |
ignored |
immediate | in | inasmuch | inc |
indeed |
indicate | indicated | indicates |
inner | insofar |
instead | into | inward | is |
isn't |
it | it'd | it'll | it's |
its |
itself | just | keep | keeps |
kept |
know | known | knows | last |
lately |
later | latter | latterly | least |
less |
lest | let | let's | like |
liked |
likely | little | look | looking |
looks |
ltd | mainly | many | may |
maybe |
me | mean | meanwhile | merely |
might |
more | moreover | most | mostly |
much |
must | my | myself | name |
namely |
nd | near | nearly | necessary |
need |
needs | neither | never |
nevertheless | new |
next | nine | no | nobody |
non |
none | noone | nor | normally |
not |
nothing | novel | now | nowhere |
obviously |
of | off | often | oh | ok |
okay | old | on | once | one |
ones | only | onto | or |
other |
others | otherwise | ought | our |
ours |
ourselves | out | outside | over |
overall |
own | particular | particularly |
per | perhaps |
placed | please | plus | possible |
presumably |
probably | provides | que | quite |
qv |
rather | rd | re | really |
reasonably |
regarding | regardless | regards |
relatively | respectively |
right | said | same | saw |
say |
saying | says | second | secondly |
see |
seeing | seem | seemed | seeming |
seems |
seen | self | selves | sensible |
sent |
serious | seriously | seven | several
| shall |
she | should | shouldn't | since |
six |
so | some | somebody | somehow |
someone |
something | sometime | sometimes |
somewhat | somewhere |
soon | sorry | specified | specify |
specifying |
still | sub | such | sup | sure
|
t's | take | taken | tell | tends
|
th | than | thank | thanks |
thanx |
that | that's | thats | the |
their |
theirs | them | themselves | then |
thence |
there | there's | thereafter | thereby
| therefore |
therein | theres | thereupon | these
| they |
they'd | they'll | they're | they've
| think |
third | this | thorough | thoroughly
| those |
though | three | through | throughout
| thru |
thus | to | together | too | took
|
toward | towards | tried | tries |
truly |
try | trying | twice | two | un
|
under | unfortunately | unless |
unlikely | until |
unto | up | upon | us | use |
used | useful | uses | using |
usually |
value | various | very | via |
viz |
vs | want | wants | was | wasn't
|
way | we | we'd | we'll | we're
|
we've | welcome | well | went |
were |
weren't | what | what's | whatever |
when |
whence | whenever | where | where's
| whereafter |
whereas | whereby | wherein | whereupon
| wherever |
whether | which | while | whither |
who |
who's | whoever | whole | whom |
whose |
why | will | willing | wish |
with |
within | without | won't | wonder |
would |
wouldn't | Да | yet | you |
you'd |
you'll | you're | you've | your |
yours |
yourself | yourselves | zero | |
|
13.9.5. Полнотекстовые ограничения
Полнотекстовые поиски поддержаны только для таблиц типов
InnoDB и
MyISAM .
- Полнотекстовые поиски не поддержаны для разделенных таблиц. См.
раздел 20.6.
- Полнотекстовые поиски могут использоваться с большинством многобайтовых
наборов символов. Исключение то, что для Unicode может использоваться набор
символов
utf8 , но не ucs2 . Хотя индексы
FULLTEXT на столбцах ucs2 не могут использоваться,
Вы можете применить поиск IN BOOLEAN MODE на столбцах
ucs2 без индекса.
Замечания для utf8 также касаются
utf8mb4 , а для ucs2 применимы к
utf16 , utf16le и utf32 .
- У идеографических языков, таких как китайский и японский язык нет
разделителей слова. Поэтому, встроенный полнотекстовый анализатор
не может определить, где слова начинаются и заканчиваются на этих и
других таких же языках.
Символьно-ориентированный полнотекстовый анализатор ngram, который
поддерживает китайский, японский и корейский (CJK) язык, и основанный на
слове плагин анализатора MeCab, который поддерживает японский язык,
обеспечены для использования с
таблицами InnoDB и MyISAM .
- Хотя использование нескольких наборов символов в пределах единственной
таблицы поддержано, все столбцы в индексе
FULLTEXT
должны использовать тот же самый набор символов и сопоставление.
- Список столбцов в
MATCH()
должен точно соответствовать списку столбцов в некоторых индексах
FULLTEXT определенных для таблицы, если это
MATCH() в
IN BOOLEAN MODE на таблице MyISAM . Для таблиц
MyISAM поиски в режиме boolean могут быть сделаны на
неиндексированных столбцах, хотя они, вероятно, будут медленными.
- Параметром
AGAINST() должно быть строковое значение, которое
является постоянным во время оценки запроса. Это исключает, например, столбец
таблицы, потому что это может отличаться для каждой строки.
- Индексные подсказки более ограничены для поисков
FULLTEXT ,
чем для не-FULLTEXT . См.
раздел 9.9.4.
- Для
InnoDB все операции DML
(INSERT ,
UPDATE ,
DELETE ) с
вовлечением столбцов с полнотекстовым индексом обработаны в момент закрытия
транзакции. Например, для INSERT вставленная строка размечена на
отдельные слова и анализируется. Отдельные слова добавлены к полнотекстовому
индексу таблицы, когда транзакция закрыта. В результате полнотекстовые поиски
возвращают только переданные данные.
- Символ '%' не поддержан для полнотекстовых поисков.
13.9.6.
Точная настройка полнотекстового поиска в MySQL
У полнотекстового поиска MySQL есть немного настраиваемых пользователем
параметров. Вы можете осуществить больший контроль над поведением
полнотекстового поиска, если у Вас есть исходные тексты
MySQL, потому что некоторые изменения требуют модификаций исходного кода. См.
раздел 2.8.
Полнотекстовый поиск тщательно настроен для эффективности. Изменение
поведения по умолчанию в большинстве случаев может фактически уменьшить
эффективность. Не изменяйте исходные тексты MySQL, если Вы не знаете
точно, что делаете!
Во время запуска сервера должно быть установлено большинство
полнотекстовых переменных, описанных в этом разделе. Перезапуск сервера
обязан изменять их, они не могут быть изменены в то время,
когда сервер работает.
Некоторые переменные требуют, чтобы Вы пересоздали индексы
FULLTEXT в Ваших таблицах. Инструкции для этого даны
позже в этом разделе.
7084
Конфигурирование минимальной и
максимальной длины слова
Минимальные и максимальные длины слов, которые будут индексированы,
определены
innodb_ft_min_token_size и
innodb_ft_max_token_size для InnoDB или
ft_min_word_len
и ft_max_word_len
для MyISAM .
Минимальная и максимальная длина слова не относится к индексам
FULLTEXT создаваемым с использованием анализатора ngram.
Маркерный размер для него определен опцией
ngram_token_size
.
После изменения любой из этих опций пересоздайте индексы
FULLTEXT , чтобы вступили в силу изменения.
Например, чтобы сделать двухсимвольные слова доступными для поиска,
Вы могли поместить следующие строки в файл опции:
[mysqld]
innodb_ft_min_token_size=2
ft_min_word_len=2
Теперь перезапустите сервер и пересоздайте индексы FULLTEXT .
Для таблиц MyISAM отметьте замечания относительно
myisamchk
в инструкциях ниже для того, чтобы пересоздать индексы MyISAM .
Конфигурирование порога поиска естественного языка
Для поисковых индексов MyISAM 50% порог для поисков
естественного языка определен особой выбранной схемой.
Чтобы отключить это, ищите следующую строку в
storage/myisam/ftdefs.h :
#define GWS_IN_USE GWS_PROB
Замените ее на:
#define GWS_IN_USE GWS_FREQ
Повторно соберите MySQL. Нет никакой потребности пересоздавать
индексы в этом случае.
Производя это изменение, Вы строго
уменьшаете способность MySQL обеспечить соответствующие значения уместности
для функции MATCH() .
Если Вы действительно должны искать такие общие слова, было бы лучше искать
с использованием IN BOOLEAN MODE , который не имеет 50% порога.
Изменение булевых полнотекстовых операторов поиска
Чтобы изменить операторы, используемые для булевых полнотекстовых поисков
в таблицах MyISAM , установите переменную
ft_boolean_syntax
. InnoDB не имеет эквивалентной установки. Эта переменная
может быть изменена в то время, как сервер работает, но Вы должны иметь
привилегию SUPER . Никакое
пересоздание индексов не нужно в этом случае. См.
раздел 6.1.5,
который описывает правила, как установить эту переменную.
Модификации набора символов
Для встроенного полнотекстового анализатора Вы можете изменить набор
символов, которые считаются символами слова, несколькими способами, как
описано в следующем списке. После создания модификации, восстановите
индексирование для каждой таблицы, которая содержит любой индекс
FULLTEXT . Предположите, что Вы хотите обработать символ дефиса
('-') как символ слова. Используйте один из этих методов:
Пересоздание полнотекстового индекса InnoDB
Если Вы изменяете полнотекстовые переменные
(
innodb_ft_min_token_size ,
innodb_ft_max_token_size ,
innodb_ft_server_stopword_table ,
innodb_ft_user_stopword_table ,
innodb_ft_enable_stopword ,
ngram_token_size
Вы должны восстановить Ваш индекс FULLTEXT
после произведения изменений. Изменение переменных
innodb_ft_min_token_size ,
innodb_ft_max_token_size или
ngram_token_size
, которые не могут быть установлены динамически, требует перезапуска
сервера и восстановления индекса.
Для пересоздания индекса FULLTEXT таблицы
InnoDB , используйте
ALTER TABLE с опциями
DROP INDEX и ADD INDEX , чтобы удалить и
обновить каждый индекс.
Оптимизация полнотекстового
индексирования InnoDB
Выполнение OPTIMIZE TABLE
на таблице с полнотекстовым индексом восстанавливает полнотекстовое
индексирование, физически удаляя удаленные логически Document ID
и объединяя записи для того же самого слова, где только возможно.
Чтобы оптимизировать полнотекстовый индекс, включите
innodb_optimize_fulltext_only и выполните
OPTIMIZE TABLE .
mysql> set GLOBAL innodb_optimize_fulltext_only=ON;
Query OK, 0 rows affected (0.01 sec)
mysql> OPTIMIZE TABLE opening_lines;
+--------------------+----------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+--------------------+----------+----------+----------+
| test.opening_lines | optimize | status | OK |
+--------------------+----------+----------+----------+
1 row in set (0.01 sec)
Чтобы избежать длинного пересоздания полнотекстового индекса
на больших таблицах, Вы можете использовать опцию
innodb_ft_num_word_optimize , чтобы выполнить оптимизацию шаг за
шагом. Опция innodb_ft_num_word_optimize определяет число слов,
которые оптимизированы каждый раз при запуске
OPTIMIZE TABLE .
Настройка по умолчанию 2000, что означает, что 2000 слов оптимизированы
каждый раз при запуске OPTIMIZE
TABLE . Последующий запуск
OPTIMIZE TABLE
продолжит работу с того места, где завершился предыдущий.
Восстановление
полнотекстового индекса MyISAM
Если Вы изменяете полнотекстовые переменные
(ft_min_word_len
,
ft_max_word_len
или ft_stopword_file
), или если Вы изменяете файл стоп-слов непосредственно,
Вы должны восстановить Ваш индекс FULLTEXT
после произведения изменений и перезапуска сервера.
Для этого на таблице MyISAM
достаточно сделать восстановление в режиме QUICK :
mysql> REPAIR TABLE tbl_name QUICK;
Альтернативно, можно использовать
ALTER TABLE . В некоторых
случаях, это может быть быстрее, чем работа восстановления.
Каждая таблица, которая содержит любой индекс FULLTEXT ,
должна быть восстановлена. Иначе запросы к таблице могут привести
к неправильным результатам, и модификации к таблице заставят сервер
рассматривать таблицу как поврежденную и нуждающуюся в ремонте.
Если Вы используете
myisamchk, чтобы выполнить работу, которая изменяет
индексы таблицы MyISAM (например, repair или analyze),
индексы FULLTEXT должны быть восстановлены, используя
значения по умолчанию параметров для минимальной длины
слова, максимальной длины слова и файла стоп-слов, если Вы не определяете
иное. Это может привести к провалу попытки запросов.
Проблема происходит, потому что эти параметры известны только серверу.
Они не сохранены в индексных файлах MyISAM . Чтобы избежать
проблемы, если Вы изменили минимальную или максимальную длину слова или
значения файла стоп-слов, используемые сервером, определите те же самые
значения для переменных
ft_min_word_len ,
ft_max_word_len
и ft_stopword_file
для программы myisamchk
, которые Вы используете для
mysqld.
Например, если Вы установили минимальную длину слова 3, Вы можете
восстановить таблицу с
myisamchk так:
shell> myisamchk --recover --ft_min_word_len=3 tbl_name .MYI
Чтобы гарантировать, что
myisamchk и сервер используют те же самые значения для
полнотекстовых параметров, разместите их в обоих секциях
[mysqld] и [myisamchk] файла опций:
[mysqld]
ft_min_word_len=3
[myisamchk]
ft_min_word_len=3
Альтернатива использованию
myisamchk для модификации табличных индексов
MyISAM состоит в применении запросов
the REPAIR TABLE ,
ANALYZE TABLE ,
OPTIMIZE TABLE или
ALTER TABLE . Они
выполнены сервером, который знает надлежащие значения параметров.
13.9.7.
Добавление сопоставления для полнотекстовой индексации
Этот раздел описывает, как добавить новое сопоставление для полнотекстовых
поисков, используя встроенный полнотекстовый анализатор. Типовое
сопоставление походит на latin1_swedish_ci , но обработает
символ '-' как букву, а не символ пунктуации так, чтобы это
могло быть индексировано как символ слова. Общая информация о добавлении
сопоставлений дана в разделе 11.4.
Предполагается, что Вы читали это и знакомы с вовлеченными файлами.
Чтобы добавить сопоставление для полнотекстовой индексации,
используйте эту процедуру:
Добавьте сопоставление к файлу Index.xml .
ID сопоставления должен быть уникальным.
<charset name="latin1">
...
<collation name="latin1_fulltext_ci" id="1000"/>
</charset>
- Объявите порядок сортировки для сопоставления в файле
latin1.xml . В этом случае порядок может быть скопирован с
latin1_swedish_ci :
<collation name="latin1_fulltext_ci">
<map>
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF
</map>
</collation>
- Измените массив
ctype в latin1.xml .
Измените значение, соответствующее 0x2D (код символа '-' )
с 10 (пунктуация) на 01 (строчная буква). В следующем массиве это элемент в
четвертой строке, третье значение от конца.
<ctype>
<map>
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 10 10 10 10 10 10 10 01 10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
</map>
</ctype>
- Перезапустите сервер.
- Чтобы использовать новое сопоставление, включите это в определение
столбцов, которые должны его использовать:
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected (0.13 sec)
mysql> CREATE TABLE t1 (
a TEXT CHARACTER SET latin1 COLLATE latin1_fulltext_ci,
FULLTEXT INDEX(a)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.47 sec)
- Проверьте сопоставление, чтобы проверить, что дефис рассматривают
как символ слова:
mysql> INSERT INTO t1 VALUEs ('----'),('....'),('abcd');
Query OK, 3 rows affected (0.22 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t1 WHERE MATCH a AGAINST ('----' IN BOOLEAN MODE);
+------+
| a |
+------+
| ---- |
+------+
1 row in set (0.00 sec)
13.9.8.
Полнотекстовый анализатор ngram
Полнотекстовый анализатор MySQL использует пробел между словами как
разделитель, чтобы определить, где слова начинаются и заканчиваются. Это
является ограничением, работая с идеографическими языками, которые не
используют разделители слова. Чтобы обойти это ограничение, MySQL
обеспечивает полнотекстовый анализатор ngram, который поддерживает китайский,
японский и корейский язык (CJK). ngram поддержан для использования с
InnoDB и
MyISAM .
MySQL также предоставляет полнотекстовый плагин MeCab анализатора
японского языка, который размечает документы на значащие слова. Для получения
дополнительной информации см.
раздел 13.9.9.
ngram это непрерывная последовательность из
n символов данной последовательности текста.
ngram анализатор размечает последовательность текста в непрерывную
последовательность n символов. Например, Вы можете
разметить abcd для различных значений n :
n=1: 'a', 'b', 'c', 'd'
n=2: 'ab', 'bc', 'cd'
n=3: 'abc', 'bcd'
n=4: 'abcd'
Полнотекстовый анализатор ngram встроенный плагин сервера. Как и с другими
встроенными плагинами сервера, это автоматически загружено,
когда сервер запущен.
Полнотекстовый синтаксис поиска, описанный в
разделе 13.9 относится к плагину
анализатора ngram. Различия в поведении парсинга описаны в этом разделе.
Связанные параметры конфигурации, за исключением минимальных и максимальных
длин слова также применимы.
Конфигурирование маркерного размера ngram
У анализатора ngram есть значение по умолчанию маркерного размера 2
(bigram). Например, с маркерным размером 2, ngram разбирает строку
abc def на четыре маркера:
ab, bc, de и ef.
Маркерный размер ngram конфигурируется опцией
ngram_token_size
, у которой есть минимальное значение 1 и максимальное 10.
Как правило,
ngram_token_size установлен в размер самого большого маркера,
который Вы хотите искать. Если Вы намереваетесь искать только единственные
символы, надо установить
ngram_token_size в 1. Меньший маркерный размер производит меньший
полнотекстовый индекс и более быстрые поиски. Если Вы должны искать слова,
состоявшие больше, чем из одного символа, стоит установить
ngram_token_size
соответственно. Например, Happy Birthday
Г■÷Ф≈╔Е©╚Д╧░ в простом китайском, где Г■÷Ф≈╔
birthday, а Е©╚Д╧░ переводится как
happy. Чтобы искать на двухсимвольных словах, установите
ngram_token_size
в 2 или выше.
Как переменная только для чтения,
ngram_token_size
может быть установлена как часть строки запуска
или в конфигурационном файле:
Следующие параметры конфигурации длины слова проигнорированы для индексов
FULLTEXT анализатором ngram:
innodb_ft_min_token_size ,
innodb_ft_max_token_size ,
ft_min_word_len
и ft_max_word_len
.
Создание индексов FULLTEXT для ngram
Чтобы создать индекс FULLTEXT , который использует анализатор
ngram, определите WITH PARSER ngram в
CREATE TABLE ,
ALTER TABLE или
CREATE INDEX .
Следующий пример демонстрирует составление таблицы с индексом
ngram FULLTEXT , вставляя типовые данные (текст на
упрощенном китайском) и рассматривая размеченные данные в таблице
INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE .
mysql> USE test;
mysql> CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT, FULLTEXT (title,body)
WITH PARSER ngram) ENGINE=InnoDB CHARACTER SET utf8mb4;
mysql> SET NAMES utf8mb4;
INSERT INTO articles (title,body) VALUES
('Ф∙╟Ф█╝Е╨⌠Г╝║Г░├','Е°╗Ф°╛Ф∙≥Г╗▀Д╦╜Ф┬▒Е╟├Е░▒Д╫═Е╠∙Г╓╨Е╕┌Д╫∙Г╝║Г░├Ф∙╟Ф█╝Е╨⌠'),
('Ф∙╟Ф█╝Е╨⌠Е╨■Г■╗Е╪─Е▐▒','Е╜╕Д╧═Е╪─Е▐▒Ф∙╟Ф█╝Е╨⌠Е╨■Г■╗Г╗▀Е╨▐');
mysql> SET GLOBAL innodb_ft_aux_table="test/articles";
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
ORDER BY doc_id, position;
Добавить индекс FULLTEXT к существующей таблице Вы можете,
используя ALTER TABLE или
CREATE INDEX . Например:
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT) ENGINE=InnoDB CHARACTER SET utf8;
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title, body)
WITH PARSER ngram;
# Или:
CREATE FULLTEXT INDEX ft_index ON articles (title, body) WITH PARSER ngram;
Обработка пробелов в ngram
Анализатор ngram устраняет пробелы, разбирая текст. Например:
Обработка стоп-слов в ngram
Встроенный в MySQL полнотекстовый анализатор сравнивает слова с записями в
списке стоп-слов. Если слово равно записи в списке стоп-слов, оно будет
исключено из индексирования. Для анализатора ngram обработка стоп-слов
выполнена по-другому. Вместо исключения маркеров, которые равны записям в
списке стоп-слов, анализатор ngram исключает маркеры, которые
содержат стоп-слова. Например, приняв
ngram_token_size=2
, документ, который содержит a,b разберется как
a, и ,b. Если запятая (,)
определена как стоп-слово, a, и ,b
исключены из индексирования, потому что они содержат запятую.
По умолчанию, ngram использует список стоп-слов, который содержит список
английского стоп-слов. Для списка стоп-слов применимого к китайскому,
японскому или корейскому языку Вы должны создать свой собственный. Для
информации о создании списка стоп-слов см.
раздел 13.9.4.
Игнорируются стоп-слова с длиной больше
ngram_token_size
.
Поиск терминов в ngram
Для поиска в режиме режиме естественного языка
критерий поиска преобразован в союз слов в ngram. Например, строка
abc (
ngram_token_size=2 ) станет ab bc.
Учитывая два документа, один содержащий ab, другой
abc, критерий поиска ab bc
соответствует обоим документам.
Для режима boolean search
критерий поиска преобразован в поисковую фразу ngram. Например, строка
'abc' (ngram_token_size=2
) разберется на 'ab bc'. Учитывая два документа, один
содержащий 'ab' и другой содержащий 'abc', фраза поиска
'ab bc' соответствует только документу, содержащему 'abc'.
Подстановочный поиск анализатора ngram
Поскольку индекс ngram FULLTEXT содержит только токены и
не содержит информацию о начале слов, подстановочные поиски могут возвратить
неожиданные результаты. Следующие примеры поведения относятся к
подстановочным поискам, использующим индексы ngram FULLTEXT :
Если понятие приставки подстановочного поиска короче маркерного
размера ngram, запрос возвращает все индексированные строки, которые содержат
маркеры ngram, начинающиеся с термина приставки. Например, при
ngram_token_size=2
поиск a* возвращает все строки, начинающиеся с
a.
- Если понятие приставки подстановочного поиска более длинно чем
маркерный размер, термин приставки преобразован в ngram-фразу, а
подстановочный оператор проигнорирован. Например, при
ngram_token_size=2
abc* превратится в ab bc.
Поиск фразы в ngram
Поисковые фразы преобразованы в поисковые фразы ngram. Например, фраза
поиска abc преобразована в ab bc, которая
возвращает документы, содержащие abc и ab bc.
Фраза поиска abc def преобразована в ab bc de ef
, которая возвращает документы, содержащие abc def и
ab bc de ef. Документ, который содержит abcdef
не будет возвращен.
13.9.9.
Полнотекстовый плагин анализатора MeCab
Полнотекстовый анализатор встроенного MySQL использует пробел между
словами как разделитель, чтобы определить, где слова начинаются и
заканчиваются. Это является ограничением, работая с идеографическими языками,
которые не используют разделители слова. Чтобы обойти это ограничение для
японского языка, MySQL предоставляет полнотекстовый плагин анализатора MeCab.
Он поддержан для использования с InnoDB
и MyISAM .
Полнотекстовый плагин анализатора MeCab это плагин для японского
языка, который размечает последовательность текста на значащие слова.
Например, MeCab размечает Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├
(Database Management) в Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧
(Database) и Г╝║Г░├ (Management).
В сравнении с ngram
полнотекстовый анализатор размечает текст в непрерывную последовательность из
n символов, где n от 1 до 10.
В дополнение к разметке текста на значащие слова MeCab индексирует, как
правило, меньше, чем ngram, а полнотекстовые поиски MeCab вообще быстрее.
Один недостаток состоит в том, что разметка документа может занять больше
времени у MeCab, чем у ngram.
Для дополнительной информации об анализаторе MeCab обратитесь к ресурсу
MeCab Documentation.
Установка плагина анализатора MeCab
Плагин анализатора MeCab требует mecab и
mecab-ipadic .
На Fedora, Debian и Ubuntu (кроме Ubuntu 12.04, где версия системы
mecab слишком стара) MySQL динамически соединяется с системной
установкой mecab , если это установлено по умолчанию. На других
поддерживаемых Unix-подобных платформах libmecab.so статически
скомпонована с libpluginmecab.so , которая расположена в каталоге
плагина MySQL. mecab-ipadic включен в исполняемый код MySQL и
находится в MYSQL_HOME \lib\mecab .
Вы можете установить mecab и mecab-ipadic
используя утилиту управления пакетами (в Fedora, Debian или Ubuntu) или
собрать mecab и mecab-ipadic из исходных текстов.
В Windows libmecab.dll находится в каталоге
MySQL bin , а mecab-ipadic в
MYSQL_HOME /lib/mecab .
Чтобы установить и сконфигурировать плагин анализатора MeCab,
выполните следующие шаги:
В конфигурационном файле MySQL установите опцию
mecab_rc_file
к местоположению конфигурационного файла mecabrc для MeCab.
Если Вы используете пакет MeCab, распределенный с MySQL
mecabrc находится в MYSQL_HOME/lib/mecab/etc/ .
[mysqld]
loose-mecab-rc-file=MYSQL_HOME/lib/mecab/etc/mecabrc
Префикс loose это
модификатор опции. Опция
mecab_rc_file
не признана MySQL, пока плагин анализатора MeCaB не установлен, но это
должно быть установлено прежде, чем попытаться установить плагин анализатора.
Префикс loose позволяет Вам перезапустить MySQL, не сталкиваясь
с ошибкой из-за непризнанной переменной.
Если Вы используете свою собственную установку MeCab или создаете MeCab из
исходных текстов, местоположение файла опций mecabrc
может быть другим.
- Также в конфигурационном файле MySQL установите минимальный маркерный
размер в 1 или 2, которые являются значениями, рекомендуемыми для
использования с анализатором MeCab. Для таблиц
InnoDB
минимальный маркерный размер определен опцией
innodb_ft_min_token_size , у которой есть значение по умолчанию 3.
Для таблиц MyISAM минимальный маркерный размер определен опцией
ft_min_word_len
(значение по умолчанию 4).
[mysqld]
innodb_ft_min_token_size=1
- Измените конфигурационный файл
mecabrc , чтобы определить
словарь, который Вы хотите использовать. Пакет mecab-ipadic
включает три словаря (ipadic_euc-jp , ipadic_sjis и
ipadic_utf-8 ). Конфигурационный файл mecabrc ,
поставляемый с MySQL содержит запись, подобную следующему:
dicdir = /path/to/mysql/lib/mecab/lib/mecab/dic/ipadic_euc-jp
Чтобы использовать словарь ipadic_utf-8 ,
модифицируйте запись так:
dicdir=MYSQL_HOME /lib/mecab/dic/ipadic_utf-8
Если Вы используете свою собственную установку MeCab или создали MeCab из
исходных текстов, значение по умолчанию dicdir в файле
mecabrc будет отличаться, соответственно координатам словарей.
После того, как плагин анализатора MeCab установлен, Вы можете
использовать статусную переменную
mecab_charset ,
чтобы просмотреть набор символов, используемый MeCab. Три словаря MeCab,
представленные в MySQL, поддерживают следующие наборы символов.
mecab_charset
только сообщает о первом поддержанном наборе символов. Например,
словарь ipadic_utf-8 поддерживает
utf8 и utf8mb4 .
mecab_charset
всегда сообщает о utf8 , когда этот словарь используется.
Перезапустите MySQL.
- Установите плагин анализатора MeCab:
Плагин анализатора MeCab установлен, используя синтаксис
INSTALL PLUGIN .
Имя плагина mecab , совместно используемое имя
библиотеки libpluginmecab.so .
INSTALL PLUGIN mecab SONAME 'libpluginmecab.so';
После того, как установлен, плагин анализатора MeCab загружается
при каждом нормальном перезапуске MySQL.
- Проверьте, что плагин анализатора MeCab загружен, используя
SHOW PLUGINS .
mysql> SHOW PLUGINS;
Плагин mecab должен появиться в списке плагинов.
Создание индекса FULLTEXT, который
использует анализатор MeCab
Чтобы создать индекс FULLTEXT , который использует
анализатор mecab, определите WITH PARSER ngram с
CREATE TABLE ,
ALTER TABLE или
CREATE INDEX .
Этот пример демонстрирует составление таблицы с индексом
mecab FULLTEXT , вставляя типовые данные и
рассматривая размеченные данные в таблице
INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE :
mysql> USE test;
mysql> CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT,
FULLTEXT (title,body) WITH PARSER mecab) ENGINE=InnoDB CHARACTER SET utf8;
mysql> SET NAMES utf8;
mysql> INSERT INTO articles (title,body) VALUES
('Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├','Ц│⌠Ц│╝Ц┐│Ц┐╔Ц┐╪Ц┐┬Ц┐╙Ц┌╒Ц┐╚Ц│╖Ц│╞Ц─│Г╖│Ц│╞Ц│╘Ц│╝Ц┌┬Ц│├Ц│╚Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Ц┌▓Г╝║Г░├Ц│≥Ц┌▀Ф√╧ФЁ∙Ц┌▓Г╢╧Д╩▀Ц│≈Ц│╬Ц│≥'),
('Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Ц┌╒Ц┐≈Ц┐╙Ц┌╠Ц┐╪Ц┌╥Ц┐╖Ц┐ЁИ√▀Г≥╨','Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Ц┌╒Ц┐≈Ц┐╙Ц┌╠Ц┐╪Ц┌╥Ц┐╖Ц┐ЁЦ┌▓И√▀Г≥╨Ц│≥Ц┌▀Ц│⌠Ц│╗Ц┌▓Е╜╕Ц│╤');
mysql> SET GLOBAL innodb_ft_aux_table="test/articles";
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
ORDER BY doc_id, position;
Чтобы добавить индекс FULLTEXT к существующей таблице, Вы
можете использовать ALTER TABLE
или CREATE INDEX :
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), body TEXT) ENGINE=InnoDB CHARACTER SET utf8;
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title,body)
WITH PARSER mecab;
# или:
CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER mecab;
Обработка пробелов анализатором MeCab
Анализатор MeCab использует пробелы в качестве разделителей в строках
запроса. Например, анализатор MeCab размечает 'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧ Г╝║Г░├'
как 'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧' и 'Г╝║Г░├'.
Обработка стоп-слов анализатором MeCab
По умолчанию анализатор MeCab использует короткий список английских
стоп-слов. Поскольку список стоп-слов перечисляет применимые к японскому
языку слова, Вы должны создать свой собственный. Для информации о создании
списка стоп-слов см.
раздел 13.9.4.
Поиск термина анализатором MeCab
Для поиска в режиме естественного языка критерий поиска преобразован в
союз маркеров. Например, 'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├' преобразуется в
'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧ Г╝║Г░├'.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body)
AGAINST('Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├' IN NATURAL LANGUAGE MODE);
Для булева поиска критерий преобразован во фразу поиска. Например,
'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├' преобразуется в
'"Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧ Г╝║Г░├"'.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body)
AGAINST('Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├' IN BOOLEAN MODE);
Подстановочный поиск анализатором MeCab
Подстановочные критерии поиска не размечены. Поиск
'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├*' выполнен на префиксе
'Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├'.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body)
AGAINST('Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧*' IN BOOLEAN MODE);
Поиск фразы анализатором MeCab
Фразы размечены. Например, "Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├" размечена как
"Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧ Г╝║Г░├".
SELECT COUNT(*) FROM articles WHERE MATCH(title,body)
AGAINST('"Ц┐┤Ц┐╪Ц┌©Ц┐≥Ц┐╪Ц┌╧Г╝║Г░├"' IN BOOLEAN MODE);
Установка MeCab из двоичного дистрибутива
Этот раздел описывает, как установить mecab
и mecab-ipadic из двоичного дистрибутива, используя утилиту
управления пакетами. Например, на Fedora Вы можете использовать Yum,
чтобы выполнить установку:
yum mecab-devel
На Debian или Ubuntu Вы можете выполнить установку через APT:
apt-get install mecab
apt-get install mecab-ipadic
Установка MeCab из исходных текстов
Если Вы хотите создать mecab и
mecab-ipadic из исходных текстов,
основные шаги установки обеспечены ниже. Для дополнительной информации
обратитесь к документации MeCab.
Загрузите tar.gz пакеты для mecab и
mecab-ipadic с
http://taku910.github.io/mecab/#download.
- Установите
mecab :
tar zxfv mecab-0.996.tar
cd mecab-0.996
./configure
make
make check
su
make install
- Установите
mecab-ipadic :
tar zxfv mecab-ipadic-2.7.0-20070801.tar
cd mecab-ipadic-2.7.0-20070801
./configure
make
su
make install
- Соберите MySQL, используя опцию
WITH_MECAB для
CMake. Установите опцию
WITH_MECAB
в system , если Вы установили
mecab и mecab-ipadic в места по умолчанию.
-DWITH_MECAB=system
Если Вы определили пользовательский каталог установки, установите
WITH_MECAB
к пользовательскому каталогу. Например:
-DWITH_MECAB=/path/to/mecab
13.10. Функции и операторы преобразования
Таблица 13.14.
Функции и операторы преобразования
Имя | Описание |
BINARY
| Преобразует обычную строку в двоичную |
CAST()
| Приводит значение к определенному типу |
CONVERT()
| Возвращает значение в качестве определенного типа
|
Функции и операторы преобразования включают преобразование значений одного
типа данных в другой.
CONVERT() с
параметром USING обеспечивает способ преобразовать данные между
различными наборами символов:
CONVERT(expr USING transcoding_name )
В MySQL транскодирующие имена то же самое, что и соответствующие
имена набора символов. Примеры:
SELECT CONVERT(_latin1'Mц╪ller' USING utf8);
INSERT INTO utf8_table (utf8_column)
SELECT CONVERT(latin1_column USING utf8) FROM latin1_table;
Вы можете также использовать
CONVERT() без USING или
CAST() , чтобы
преобразовать строки между различными наборами символов:
CONVERT(string , CHAR[(N )]
CHARACTER SET charset_name )
CAST(string AS CHAR[(N )]
CHARACTER SET charset_name )
Примеры:
SELECT CONVERT('test', CHAR CHARACTER SET utf8);
SELECT CAST('test' AS CHAR CHARACTER SET utf8);
Если Вы определяете CHARACTER SET
charset_name как показано,
получающийся набор символов и сопоставление
charset_name
и сопоставление по умолчанию для charset_name .
Если Вы опускаете CHARACTER SET charset_name
, получающийся набор символов и сопоставление определены переменными
character_set_connection и
collation_connection
, которые определяют набор символов соединения и сопоставление
по умолчанию (см. раздел 11.1.4).
Пункт COLLATE не разрешен в пределах вызова
CONVERT() или
CAST() , но Вы можете
применить это к функциональному результату. Например, это является законным:
SELECT CAST('test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;
Но это незаконно:
SELECT CAST('test' AS CHAR CHARACTER SET utf8 COLLATE utf8_bin);
Обычно Вы не можете сравнить значения BLOB
или другие двоичные строки нечувствительным к регистру способом,
потому что двоичные строки используют набор символов binary ,
у которого нет никакого сопоставления с понятием регистра символов.
Чтобы выполнить нечувствительное к регистру сравнение, используйте функцию
CONVERT() или
CAST() , чтобы
преобразовать значение в недвоичную строку. Сравнения получающейся строки
используют ее сопоставление. Например, если у конверсионного набора символов
результата есть нечувствительное к регистру сопоставление, операция
LIKE
не является чувствительной к регистру:
SELECT 'A' LIKE CONVERT(blob_col USING latin1)
FROM tbl_name ;
Чтобы использовать иной набор символов, замените его именем
latin1 в предыдущем запросе. Чтобы определить особое
сопоставление для переделанной строки, используйте предложение
COLLATE после вызова
CONVERT() :
SELECT 'A' LIKE CONVERT(blob_col USING latin1)
COLLATE latin1_german1_ci
FROM tbl_name ;
CONVERT() и
CAST() могут
использоваться более широко для того, чтобы сравнить строки, которые
представлены в различных наборах символов.
Преобразование набора символов также полезное преобразование двоичных
строк. LOWER() и
UPPER() неэффективны,
когда применено непосредственно к двоичным строкам, потому что понятие
регистра не применяется. Чтобы выполнить смену регистра двоичной строки,
сначала преобразуйте это в недвоичную строку:
mysql> SET @str = BINARY 'New York';
mysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));
+-------------+-----------------------------------+
| LOWER(@str) | LOWER(CONVERT(@str USING latin1)) |
+-------------+-----------------------------------+
| New York | new york |
+-------------+-----------------------------------+
Если Вы преобразовываете индексированные столбцы, применяя
BINARY ,
CAST() или
CONVERT() ,
MySQL, возможно, не в состоянии использовать индексирование эффективно.
Функции конвертации полезны для создания столбца с определенным типом в
CREATE TABLE ... SELECT :
mysql> CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE) AS c1;
mysql> SHOW CREATE TABLE new_table\G
*************************** 1. row ***************************
Table: new_table
Create Table: CREATE TABLE `new_table` (`c1` date DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=latin1
Функции конвертации также могут быть полезными для сортировки столбцов
ENUM в лексическом порядке. Обычно
сортировка ENUM происходит,
используя внутренние числовые значения. Преобразование значений в
CHAR
дает результаты в лексическом виде:
SELECT enum_col FROM tbl_name
ORDER BY CAST(enum_col AS CHAR);
CAST()
также изменяет результат, если Вы используете его в качестве части более
сложного выражения, например,
CONCAT('Date: ',CAST(NOW() AS DATE)) .
Для временных значений есть небольшая потребность использовать
CAST() , чтобы
извлечь данные в различных форматах. Вместо этого используйте такие функции:
EXTRACT() ,
DATE_FORMAT() или
TIME_FORMAT() .
Чтобы преобразовать строку к числу, Вы обычно должны просто использовать
строковое значение в числовом контексте:
mysql> SELECT 1+'1';
-> 2
Это также истина для шестнадцатеричных и двоичных литералов, которые
являются двоичными строками по умолчанию:
mysql> SELECT X'41', X'41'+0;
-> 'A', 65
mysql> SELECT b'1100001', b'1100001'+0;
-> 'a', 97
Строка, используемая в арифметической работе, преобразована в число с
плавающей запятой во время оценки выражения.
Число, используемое в строковом контексте, преобразовано в строку:
mysql> SELECT CONCAT('hello you ',2);
-> 'hello you 2'
MySQL поддерживает арифметику 64-bit для значений со знаком и без него.
Если Вы используете числовые операторы
(+ или
- , например)
и один из операндов целое число без знака, результат без знака
по умолчанию. Вы можете переопределить это при использовании оператора
SIGNED или UNSIGNED , чтобы привести значение к
соответствующему 64-bit целому числу.
mysql> SELECT 1 - 2;
-> -1
mysql> SELECT CAST(1 - 2 AS UNSIGNED);
-> 18446744073709551615
mysql> SELECT CAST(CAST(1 - 2 AS UNSIGNED) AS SIGNED);
-> -1
Если любой операнд значение с плавающей запятой, результат значение с
плавающей запятой и не затронут предыдущим правилом. В этом контексте
значения столбцов DECIMAL
расценены как значения с плавающей запятой.
mysql> SELECT CAST(1 AS UNSIGNED) - 2.0;
-> -1.0
Режим SQL затрагивает результат конверсионных операций (см.
раздел 6.1.8). Например:
Следующий список описывает доступные функции конвертации:
BINARY
expr
Оператор BINARY
преобразовывает выражение в двоичную строку. Обычное использование для
BINARY
это вынудить сравнение строки символов быть сделанным побайтно, а не
посимвольно, в действительности становясь чувствительным к регистру.
Оператор BINARY
также заставляет конечные пробелы в сравнениях быть существенными.
mysql> SELECT 'a' = 'A';
-> 1
mysql> SELECT BINARY 'a' = 'A';
-> 0
mysql> SELECT 'a' = 'a ';
-> 1
mysql> SELECT BINARY 'a' = 'a ';
-> 0
В сравнении BINARY
затрагивает всю работу: это может быть задано перед любым операндом с тем
же самым результатом.
В целях преобразования строковое выражение в двоичную строку,
эти конструкции эквивалентны:
BINARY expr
CAST(expr AS BINARY)
CONVERT(expr USING BINARY)
Если значение буквальная строка, это может определяться как двоичная
строка, не выполняя преобразования при использовании префикса
набора символов _binary :
mysql> SELECT 'a' = 'A';
-> 1
mysql> SELECT _binary 'a' = 'A';
-> 0
Оператор BINARY
в выражениях отличается в действительности от признака BINARY
в символьных определениях столбца. Символьный столбец, определенный с
признаком BINARY имеет назначенный табличный набор символов
по умолчанию и двоичное (_bin ) сопоставление для того набора
символов. У каждого недвоичного набора символов есть сопоставление
_bin . Например, двоичное сопоставление для набора символов
utf8 utf8_bin , так, если табличный набор символов
по умолчанию utf8 , эти определения двух столбцов эквивалентны:
CHAR(10) BINARY
CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
Использование CHARACTER SET binary в определении
CHAR ,
VARCHAR или
TEXT
заставляет столбец быть обработанным как соответствующий двоичной строковый
тип данных. Например, следующие пары определений эквивалентны:
CHAR(10) CHARACTER SET binary
BINARY(10)
VARCHAR(10) CHARACTER SET binary
VARBINARY(10)
TEXT CHARACTER SET binary
BLOB
CAST(expr AS
type )
Функция CAST()
берет выражение любого типа и производит значение результата указанного типа,
подобно CONVERT() .
CAST()
стандартный синтаксис SQL.
CONVERT(expr ,
type ) ,
CONVERT(expr
USING transcoding_name )
Функция CONVERT()
берет выражение любого типа и производит значение результата указанного типа.
Обсуждение синтаксиса
CONVERT(expr ,
type ) также относится к
CAST(expr AS
type ) , которая эквивалентна.
CONVERT(... USING ...)
стандартный синтаксис SQL. Форма
CONVERT() без USING синтаксис ODBC.
CONVERT() с
USING переводит между различными наборами символов. В MySQL
транскодирующие имена то же самое, что и соответствующие имена набора
символов. Например, этот запрос преобразовывает строку 'abc'
в наборе символов по умолчанию к соответствующей строке в
наборе символов utf8 :
SELECT CONVERT('abc' USING utf8);
CONVERT() без
USING и CAST()
берут выражение и значение type , определяющее тип
результата. Здесь такие type допустимы:
BINARY[(N )]
Производит строку с типом данных
BINARY . См.
раздел 12.4.2
для описания того, как это затрагивает сравнения. Если длина
N задана, BINARY(N )
заставляет преобразование использовать не больше, чем
N байтов параметра. Значения короче, чем
N байтов дополнены
with 0x00 до длины N .
CHAR[(N )]
[charset_info ]
Производит строку типа
CHAR . Если длина
optional length N задана,
CHAR(N )
заставляет преобразование использовать не больше, чем
N байтов параметра. Никакого дополнения не происходит
для значений короче, чем N .
Без charset_info CHAR
производит строку с набором символов по умолчанию. Чтобы определить набор
символов явно, значения charset_info разрешены:
Во всех случаях у строки есть сопоставление
по умолчанию для набора символов.
DATE
Производит значение DATE .
DATETIME
Производит значение DATETIME
.
DECIMAL[(M [,D ])]
Производит значение DECIMAL
. Если дополнительные параметры
M и D заданы,
они определяют максимальное количество цифр (точность) и число цифр после
десятичной запятой (масштаб).
JSON
Производит значение JSON .
NCHAR[(N )]
Аналогично CHAR , но производит строку с национальным набором
символов. См. раздел 11.1.3.7.
В отличие от CHAR , NCHAR не разрешает
сопроводительную информацию о наборе символов, которая будет определена.
SIGNED [INTEGER]
Производит значение signed integer.
TIME
Производит значение TIME .
UNSIGNED [INTEGER]
Производит значение unsigned integer.
13.11. Функции XML
Таблица 13.15. Функции XML
Имя | Описание
|
ExtractValue() | Извлекает значение из строки XML,
используя нотацию XPath |
UpdateXML()
| Возвратит замененный фрагмент XML
|
Этот раздел обсуждает XML и связанную функциональность в MySQL.
Возможно получить XML-отформатированный вывод из MySQL в клиентах
mysql и
mysqldump,
вызывая их с опцией --xml
.
Две функции, обеспечивающие основные возможности XPath 1.0 (XML Path
Language, version 1.0) доступны. Некоторая основная информация о синтаксисе
XPath и использовании обеспечена позже в этом разделе, однако, всестороннее
обсуждение этих тем находится вне контекста этого Руководства, и Вы должны
изучить XML Path Language
(XPath) 1.0 standard для получения нужной информации. Полезный ресурс для
плохо знакомых с XPath или кто желает получить базовые знания:
Zvon.org
XPath Tutorial, который доступен на нескольких языках.
Эти функции остаются разрабатываемыми. Мы продолжаем улучшать эти и другие
аспекты XML и функциональности XPath в MySQL 8.0. Вы можете обсудить их,
задать вопросы о них и получить справку от других пользователей на
MySQL XML User Forum.
Выражения XPath, используемые с этими функциями, поддерживают
пользовательские переменные и местные сохраненные переменные программы.
Пользовательские переменные слабо проверены, локальные переменные сохраненных
программ проверены хорошо (см. также Bug #26518):
Пользовательские переменные (слабая проверка).
Переменные, использующие синтаксис $@variable_name
(то есть, пользовательские переменные), не проверены. Никакие
предупреждения или ошибки не созданы сервером, если переменная имеет
неправильный тип или не было ранее значение назначено. Это также означает,
что пользователь полностью ответственен за любые типографские ошибки, так как
никакие предупреждения не будут даны если (например)
$@myvariabl используется вместо $@myvariable .
Пример:
mysql> SET @xml = '<a><b>X</b><b>Y</b></a>';
Query OK, 0 rows affected (0.00 sec)
mysql> SET @i =1, @j = 2;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @i, ExtractValue(@xml, '//b[$@i]');
+----+--------------------------------+
| @i | ExtractValue(@xml, '//b[$@i]') |
+----+--------------------------------+
| 1 | X |
+----+--------------------------------+
1 row in set (0.00 sec)
mysql> SELECT @j, ExtractValue(@xml, '//b[$@j]');
+----+--------------------------------+
| @j | ExtractValue(@xml, '//b[$@j]') |
+----+--------------------------------+
| 2 | Y |
+----+--------------------------------+
1 row in set (0.00 sec)
mysql> SELECT @k, ExtractValue(@xml, '//b[$@k]');
+------+--------------------------------+
| @k | ExtractValue(@xml, '//b[$@k]') |
+------+--------------------------------+
| NULL | |
+------+--------------------------------+
1 row in set (0.00 sec)
- Переменные в сохраненных программах (сильная проверка).
Переменные, использующие синтаксис
$variable_name
могут быть объявлены и использоваться с этими функциями, когда их называют
внутренними сохраненными программами. Такие переменные являются локальными
к сохраненной программе, в которой они определены, они сильно проверены
на тип и значение.
Пример:
mysql> DELIMITER |
mysql> CREATE PROCEDURE myproc ()
-> BEGIN
-> DECLARE i INT DEFAULT 1;
-> DECLARE xml VARCHAR(25) DEFAULT '<a>X</a><a>Y</a><a>Z</a>';
->
-> WHILE i < 4 DO
-> SELECT xml, i, ExtractValue(xml, '//a[$i]');
-> SET i = i+1;
-> END WHILE;
-> END |
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
mysql> CALL myproc();
+--------------------------+---+------------------------------+
| xml | i | ExtractValue(xml, '//a[$i]') |
+--------------------------+---+------------------------------+
| <a>X</a><a>Y</a><a>Z</a> | 1 | X |
+--------------------------+---+------------------------------+
1 row in set (0.00 sec)
+--------------------------+---+------------------------------+
| xml | i | ExtractValue(xml, '//a[$i]') |
+--------------------------+---+------------------------------+
| <a>X</a><a>Y</a><a>Z</a> | 2 | Y |
+--------------------------+---+------------------------------+
1 row in set (0.01 sec)
+--------------------------+---+------------------------------+
| xml | i | ExtractValue(xml, '//a[$i]') |
+--------------------------+---+------------------------------+
| <a>X</a><a>Y</a><a>Z</a> | 3 | Z |
+--------------------------+---+------------------------------+
1 row in set (0.01 sec)
Параметры. Переменные использованные в выражениях XPath в
сохраненных функциях, которые передают как параметры, также
подвергаются сильной проверке.
Выражения, содержащие пользовательские переменные или переменные,
локальные к сохраненным программам, должны (за исключением нотации)
соответствовать правилам для выражений XPath, содержащих переменные, как
дано в спецификации XPath 1.0.
Пользовательская переменная, используемая, чтобы сохранить выражение
XPath, обработана как пустая строка. Из-за этого не возможно сохранить
выражение XPath как пользовательскую переменную (Bug #32911).
ExtractValue(
xml_frag , xpath_expr )
ExtractValue()
берет два строковых параметра, фрагмент разметки XML
xml_frag и выражение XPath
xpath_expr (также именуемое locator).
Это возвращает текст (CDATA ) из первого текстового узла, который
является дочерним элементом или элементом, соответствующим выражениею XPath.
Использование этой функции эквивалентно выполнению соответствия, используя
xpath_expr после добавления /text() .
Другими словами,
ExtractValue('<a><b>Sakila</b></a>', '/a/b')
и
ExtractValue('<a><b>Sakila</b></a>', '/a/b/text()')
приведут к тому же самому результату.
Если многократные соответствия найдены, контент первого дочернего
текстового узла каждого элемента соответствия возвращен (в соответствующем
порядке) как единственная, разграниченная пробелами строка.
Если никакой текстовый узел соответствия не найден для выражения
(включая неявное /text() ) по любой причине, пока
xpath_expr верно, а xml_frag
состоит из элементов, которые должным образом вложены и закрыты, вернется
пустая строка. Никакое различие не сделано между соответствием на пустом
элементе и никаким соответствием вообще.
Если Вы должны определить, не был ли элемент соответствия найден в
in xml_frag или такой элемент был найден, но не
содержал дочерних текстовых узлов, Вы должны проверить результат выражения,
которое использует функция XPath count() . Например, оба эти
запроса возвращают пустую строку, как показано:
mysql> SELECT ExtractValue('<a><b/></a>', '/a/b');
+-------------------------------------+
| ExtractValue('<a><b/></a>', '/a/b') |
+-------------------------------------+
| |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue('<a><c/></a>', '/a/b');
+-------------------------------------+
| ExtractValue('<a><c/></a>', '/a/b') |
+-------------------------------------+
| |
+-------------------------------------+
1 row in set (0.00 sec)
Однако, Вы можете определить, был ли фактически соответствующий
элемент, используя следующее:
mysql> SELECT ExtractValue('<a><b/></a>', 'count(/a/b)');
+-------------------------------------+
| ExtractValue('<a><b/></a>', 'count(/a/b)') |
+-------------------------------------+
| 1 |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue('<a><c/></a>', 'count(/a/b)');
+-------------------------------------+
| ExtractValue('<a><c/></a>', 'count(/a/b)') |
+-------------------------------------+
| 0 |
+-------------------------------------+
1 row in set (0.01 sec)
ExtractValue()
возвращает только CDATA , и не возвращает ни тегов, которые
могли бы содержаться в пределах соответствующего тега, ни любого их контента
(результат возвратится как val1 в следующем примере).
mysql> SELECT
-> ExtractValue('<a>ccc<b>ddd</b></a>', '/a') AS val1,
-> ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b') AS val2,
-> ExtractValue('<a>ccc<b>ddd</b></a>', '//b') AS val3,
-> ExtractValue('<a>ccc<b>ddd</b></a>', '/b') AS val4,
-> ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+------+------+------+------+---------+
| val1 | val2 | val3 | val4 | val5 |
+------+------+------+------+---------+
| ccc | ddd | ddd | | ddd eee |
+------+------+------+------+---------+
Эта функция использует текущее сопоставление SQL для того, чтобы сделать
сравнения с contains() ,
выполняя тоже самое сопоставление как другие строковые функции (такие, как
CONCAT() ),
принимая во внимание сопоставление их аргументов, см.
раздел 11.1.8.4 для
объяснения правил, управляющих этим поведением.
NULL возвращен, если xml_frag
содержит элементы, которые должным образом не вложены или закрыты, и
предупреждение произведено, как показано в этом примере:
mysql> SELECT ExtractValue('<a>c</a><b', '//a');
+-----------------------------------+
| ExtractValue('<a>c</a><b', '//a') |
+-----------------------------------+
| NULL |
+-----------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1525
Message: Incorrect XML value: 'parse error at line 1 pos 11:
END-OF-INPUT unexpected ('>' wanted)'
1 row in set (0.00 sec)
mysql> SELECT ExtractValue('<a>c</a><b/>', '//a');
+-------------------------------------+
| ExtractValue('<a>c</a><b/>', '//a') |
+-------------------------------------+
| c |
+-------------------------------------+
1 row in set (0.00 sec)
UpdateXML(xml_target
, xpath_expr ,
new_xml )
Эта функция заменяет единственную часть данного фрагмента XML
xml_target на новый new_xml
и затем возвращает измененный XML. Часть xml_target
соответствует выражению XPath xpath_expr .
Если никакое соответствие выражения xpath_expr
не найдено, или если многократные соответствия найдены, функция возвращает
оригинальный фрагмент xml_target .
Все три параметра должны быть строками.
mysql> SELECT
-> UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
-> UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
-> UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
-> UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
-> UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
-> \G
*************************** 1. row ***************************
val1: <e>fff</e>
val2: <a><b>ccc</b><d></d></a>
val3: <a><e>fff</e><d></d></a>
val4: <a><b>ccc</b><e>fff</e></a>
val5: <a><d></d><b>ccc</b><d></d></a>
Обсуждение подробно синтаксиса XPath и его использования вне контекста
этого руководства. Пожалуйста, см.
XML Path Language
(XPath) 1.0 specification.
Описания и примеры некоторых основных выражений XPath:
/tag
Соответствует <tag /> , если и
только если <tag /> элемент корня.
Пример: /a имеет соответствие в
<a><b/></a>
потому что это соответствует наиболее удаленному (корневому) тегу. Это не
соответствует внутреннему элементу a в
<b><a/></b> потому что в этом случае это
дочерний элемент другого элемента.
/tag1 /tag2
Соответствует <tag2 /> , если и
только если это дочерний элемент <tag1 />
и <tag1 /> элемент корня.
Пример: /a/b соответствует элементу
b в фрагменте XML
<a><b/></a> потому что это дочерний элемент
элемента корня a . У этого нет соответствия в
<b><a/></b> потому что в этом случае
b элемент корня (и следовательно дочерний элемент
никакого другого элемента). И при этом у выражения XPath нет соответствия в
<a><c><b/></c></a> : здесь
b потомок a ,
но не фактический дочерний элемент a .
Эта конструкция является растяжимой к трем или больше элементам.
Например, выражение XPath /a/b/c соответствует элементу
c во фрагменте
<a><b><c/></b></a> .
//tag
Соответствует любому экземпляру
<tag > .
Пример: //a соответствует элементу
a в любом из:
<a><b><c/></b></a> ;
<c><a><b/></a></b> ;
<c><b><a/></b></c> .
// может быть объединен с
/ . Например, //a/b соответствует
элементу b в любом из фрагментов
<a><b/></a> или
<a><b><c/></b></a> .
//tag эквивалент
/descendant-or-self::*/tag .
Распространенная ошибка состоит в том, чтобы перепутать это с
/descendant-or-self::tag ,
хотя последнее выражение может фактически привести к
совсем другим результатам:
mysql> SET @xml = '<a><b><c>w</c><b>x</b><d>y</d>z</b></a>';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @xml;
+-----------------------------------------+
| @xml |
+-----------------------------------------+
| <a><b><c>w</c><b>x</b><d>y</d>z</b></a> |
+-----------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue(@xml, '//b[1]');
+------------------------------+
| ExtractValue(@xml, '//b[1]') |
+------------------------------+
| x z |
+------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue(@xml, '//b[2]');
+------------------------------+
| ExtractValue(@xml, '//b[2]') |
+------------------------------+
| |
+------------------------------+
1 row in set (0.01 sec)
mysql> SELECT ExtractValue(@xml, '/descendant-or-self::*/b[1]');
+---------------------------------------------------+
| ExtractValue(@xml, '/descendant-or-self::*/b[1]') |
+---------------------------------------------------+
| x z |
+---------------------------------------------------+
1 row in set (0.06 sec)
mysql> SELECT ExtractValue(@xml, '/descendant-or-self::*/b[2]');
+---------------------------------------------------+
| ExtractValue(@xml, '/descendant-or-self::*/b[2]') |
+---------------------------------------------------+
| |
+---------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue(@xml, '/descendant-or-self::b[1]');
+-------------------------------------------------+
| ExtractValue(@xml, '/descendant-or-self::b[1]') |
+-------------------------------------------------+
| z |
+-------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ExtractValue(@xml, '/descendant-or-self::b[2]');
+-------------------------------------------------+
| ExtractValue(@xml, '/descendant-or-self::b[2]') |
+-------------------------------------------------+
| x |
+-------------------------------------------------+
1 row in set (0.00 sec)
Оператор * действует как подстановка,
которая соответствует любому элементу. Например, выражение
/*/b соответствует элементу b
в любом из фрагментов XML <a><b/></a> или
<c><b/></c> . Однако, выражение не производит
соответствие во фрагменте <b><a/></b>
потому что b должен быть дочерним элементом
некоторого другого элемента. Подстановочный знак может использоваться в любой
позиции: выражение /*/b/* будет соответствовать любому дочернему
элементу b , который является самостоятельно
не элементом корня.
- Вы можете соответствовать любому из нескольких локаторов, используя
оператор
| (UNION ).
Например, выражение //b|//c соответствует всем элементам
b и c в цели XML.
- Также возможно соответствовать элементу, основываясь на значении одного
или больше его признаков. Это сделано через использование синтаксиса
tag [@attribute ="
value "] . Например, выражение
//b[@id="idB"] соответствует второму элементу
b во фрагменте
<a><b id="idA"/><c/><b id="idB"/></a>
. Чтобы соответствовать любому элементу,
имеющему attribute ="value "
, используйте выражение XPath
//*[attribute ="value "]
.
Чтобы фильтровать многократные значения атрибута, просто используйте
многократные пункты сравнения признака по очереди. Например, выражение
//b[@c="x"][@d="y"] соответствует элементу
<b c="x" d="y"/> где угодно в данном фрагменте XML.
Чтобы найти элементы, для которых тот же самый признак соответствует
любому из нескольких значений, Вы можете использовать много локаторов,
к которым присоединяется оператор | .
Например, чтобы соответствовать всем элементам
b , чей признак c
имеет значение 23 или 17, используют выражение
//b[@c="23"]|//b[@c="17"] . Вы можете также использовать
логический оператор or : //b[@c="23" or @c="17"] .
Различие между or и | в том, что or
объединяет условия, а | наборы результатов.
XPath Limitations.
Синтаксис XPath, поддержанный этими функциями, в настоящее время
подвергается следующим ограничениям:
Сравнение Nodeset-to-nodeset (такое, как
'/a/b[@c=@d]' ) не поддержано.
- Все стандартные операторы сравнения XPath поддержаны (Bug #22823).
- Относительные выражения локатора решены в контексте корневого узла.
Например, рассмотрите следующий запрос и результат:
mysql> SELECT ExtractValue(
-> '<a><b c="1">X</b><b c="2">Y</b></a>',
->'a/b'
-> ) AS result;
+--------+
| result |
+--------+
| X Y |
+--------+
1 row in set (0.03 sec)
В этом случае локатор a/b приведет к /a/b .
Относительные локаторы также поддержаны в пределах предикатов.
В следующем примере d[../@c="1"] решен как
/a/b[@c="1"]/d :
mysql> SELECT ExtractValue(
->'<a>
-> <b c="1"><d>X</d></b>
-> <b c="2"><d>X</d></b>
-></a>',
->'a/b/d[../@c="1"]')
-> AS result;
+--------+
| result |
+--------+
| X |
+--------+
1 row in set (0.00 sec)
- Префиксы локаторов с выражениями, которые оценивают как скалярные
значения, включая ссылки на переменные, литералы, числа и вызовы скалярных
функций, не разрешены, и их результаты ошибочны.
- Оператор
:: не поддержан в комбинации с типами узла,
такими как следующие:
axis ::comment()
axis ::text()
axis ::processing-instructions()
axis ::node()
Однако, имена тестов (такие, как
axis ::name
и axis ::* )
поддержаны, как показано в этих примерах:
mysql> SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b');
+-------------------------------------------------------+
| ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b') |
+-------------------------------------------------------+
| x |
+-------------------------------------------------------+
1 row in set (0.02 sec)
mysql> SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*');
+-------------------------------------------------------+
| ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*') |
+-------------------------------------------------------+
| x y |
+-------------------------------------------------------+
1 row in set (0.01 sec)
- Навигация Up-and-down не поддержана в случаях, когда
путь привел бы в элемент корня. Таким образом, Вы не можете использовать
выражения, которые соответствуют на потомках предков данного элемента, где
один или больше предков текущего элемента также предок элемента
корня (см. Bug #16321).
- Следующие функции XPath не поддержаны или имеют проблемы:
id()
lang()
local-name()
name()
namespace-uri()
normalize-space()
starts-with()
string()
substring-after()
substring-before()
translate()
Следующие axes не поддержаны:
following-sibling
following
preceding-sibling
preceding
Выражения XPath, переданные как параметры в
ExtractValue() и
UpdateXML() ,
могут содержать символ двоеточия (: ) в селекторах элемента,
который включает их с разметкой, использующей нотацию пространств
имен XML. Например:
mysql> SET @xml = '<a>111<b:c>222<d>333</d><e:f>444</e:f></b:c></a>';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT ExtractValue(@xml, '//e:f');
+-----------------------------+
| ExtractValue(@xml, '//e:f') |
+-----------------------------+
| 444 |
+-----------------------------+
1 row in set (0.00 sec)
mysql> SELECT UpdateXML(@xml, '//b:c', '<g:h>555</g:h>');
+--------------------------------------------+
| UpdateXML(@xml, '//b:c', '<g:h>555</g:h>') |
+--------------------------------------------+
| <a>111<g:h>555</g:h></a> |
+--------------------------------------------+
1 row in set (0.00 sec)
Это подобно в некотором отношении тому, что разрешено
Apache Xalan и
и некоторыми другими анализаторами, и намного проще, чем требование
деклараций пространства имен или использования функций
namespace-uri() и local-name() .
Обработка ошибок. Для
ExtractValue() и
UpdateXML()
используемый локатор XPath должен быть допустимым, и XML, который будет
искаться, должен состоять из элементов, которые должным образом вложены и
закрыты. Если локатор недопустим, ошибка произведена:
mysql> SELECT ExtractValue('<a>c</a><b/>', '/&a');
ERROR 1105 (HY000): XPATH syntax error: '&a'
Если xml_frag не состоит из элементов, которые
должным образом вложены и закрыты, NULL
возвращен и предупреждение произведено, как показано в этом примере:
mysql> SELECT ExtractValue('<a>c</a><b', '//a');
+-----------------------------------+
| ExtractValue('<a>c</a><b', '//a') |
+-----------------------------------+
| NULL |
+-----------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1525
Message: Incorrect XML value: 'parse error at line 1 pos 11:
END-OF-INPUT unexpected ('>' wanted)'
1 row in set (0.00 sec)
mysql> SELECT ExtractValue('<a>c</a><b/>', '//a');
+-------------------------------------+
| ExtractValue('<a>c</a><b/>', '//a') |
+-------------------------------------+
| c |
+-------------------------------------+
1 row in set (0.00 sec)
Заменяющий XML, используемый в качестве третьего параметра
UpdateXML()
не проверен, чтобы определить, состоит ли это
исключительно из элементов, которые должным образом вложены и закрыты.
Инъекция XPath. Инъекция кода происходит, когда вредоносный код
введен в систему, чтобы получить несанкционированный доступ к привилегиям и
данным. Это основано на эксплуатации предположений, сделанных разработчиками
о типе и контенте ввода данных от пользователей.
XPath не исключение в этом отношении.
Общий сценарий, в котором это может произойти: приложение обрабатывает
авторизацию на основе комбинации имени для входа в систему и пароля, которые
берутся из файла XML, используя выражение XPath наподобие:
//user[login/text()='neapolitan' and password/text()='1c3cr34m']/attribute::id
Это XPath-эквивалент SQL-запроса:
SELECT id FROM users WHERE login='neapolitan' AND password='1c3cr34m';
Приложение PHP, использующее XPath, могло бы обработать процесс
входа в систему так:
<?php
$file = "users.xml";
$login= $POST["login"];
$password = $POST["password"];
$xpath = "//user[login/text()=$login and password/text()=$password]/attribute::id";
if (file_exists($file)) {
$xml = simplexml_load_file($file);
if ($result = $xml->xpath($xpath))
echo "You are now logged in as user $result[0].";
else echo "Invalid login name or password.";
}
else exit("Failed to open $file.");
?>
Никакие проверки не выполнены на вводе. Это означает, что пользователь
может ввести ' or 1=1 для имени для входа в систему и для
пароля, в итоге $xpath будет оценен как показано здесь:
//user[login/text()='' or 1=1 and password/text()='' or 1=1]/attribute::id
Так как выражение в квадратных скобках всегда оценивается как
true , это эффективно то же самое, как будто признак
id каждого элемента user
соответствет в XML-документе:
//user/attribute::id
Один путь, которым можно обойти это особое нападение: просто заключить
имена переменной в кавычки, которые будут интерполированы в определении
$xpath , принудительно конвертируя значение из Web-формы в строку:
$xpath = "//user[login/text()='$login' and password/text()='$password']/attribute::id";
Это та же самая стратегия, которая часто рекомендуется для того, чтобы
предотвратить атаки с использованием кода SQL. Вообще, методы, которым Вы
должны следовать для того, чтобы предотвратить нападения инъекции XPath,
являются теми же самыми, что касаются предотвращения инъекции SQL:
Так же, как атаки с использованием кода на SQL могут использоваться, чтобы
получить информацию о схемах базы данных, так может использоваться и инъекция
XPath: Blind XPath Injection (PDF file, 46KB).
Также важно проверить вывод, отсылаемый назад к клиенту. Рассмотрите то,
что может произойти, когда мы используем MySQL
ExtractValue() :
mysql> SELECT ExtractValue(LOAD_FILE('users.xml'),
-> '//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
-> ) AS id;
+-------------------------------+
| id |
+-------------------------------+
| 00327 13579 02403 42354 28570 |
+-------------------------------+
1 row in set (0.01 sec)
Поскольку ExtractValue()
возвращает многократные соответствия как разграниченную одинарным
интервалом строку, это нападение инъекции обеспечивает передачу всех
допустимых ID в пределах users.xml пользователю как единственную
строка вывода. Как дополнительная гарантия, Вы должны также проверить вывод
прежде, чем возвратить это пользователю. Вот простой пример:
mysql> SELECT @id = ExtractValue(
-> LOAD_FILE('users.xml'),
-> '//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT IF (
-> INSTR(@id, ' ') = 0, @id,
-> 'Unable to retrieve user ID') AS singleID;
+----------------------------+
| singleID |
+----------------------------+
| Unable to retrieve user ID |
+----------------------------+
1 row in set (0.00 sec)
Вообще, основные направления для того, чтобы возвратить данные
пользователям надежно являются теми же самыми, что касаются принятия ввода
данных от пользователя. Им можно подвести итог так:
13.12. Битовые функции и операторы
Таблица 13.16.
Битовые функции и операторы
Имя | Описание |
BIT_COUNT() | Возвратить число битов, которые установлены
|
&
| Битовое AND |
~
| Битовая инверсия |
|
| Битовое OR |
^
| Битовое XOR |
<<
| Сдвиг влево |
>>
| Сдвиг вправо |
Разрядные функции и операторы включают
BIT_COUNT() ,
BIT_AND() ,
BIT_OR() ,
BIT_XOR() ,
& ,
| ,
^ ,
~ ,
<< и
>> .
BIT_AND() ,
BIT_OR() и
BIT_XOR() это
совокупные функции, описанные в
разделе 13.19.1. До MySQL 8.0 разрядные функции и операторы требовали
параметры BIGINT (64-bit
integer) и возвращали значения BIGINT
. Не-BIGINT
параметры были преобразованы в BIGINT
до выполнения работы, и усечение могло произойти.
В MySQL 8.0 разрядные функции и операторы разрешают двоичные строковые
параметры типа BINARY ,
VARBINARY и
BLOB
и возвращают значение подобного типа, что позволяет им взять параметры и
произвести возвращаемые значения больше, чем 64 бита.
Значение этого изменения в поведении: битовые операции на двоичных
параметрах могли бы привести к различному результату в MySQL 8.0 и 5.7. Для
получения дополнительной информации об изменении, включая то, как
подготовиться в MySQL 5.7 для потенциальных несовместимостей между MySQL 5.7
и 8.0 см. Bit Functions and Operators в
MySQL 5.7 Reference Manual.
Следующий список описывает доступные разрядные функции и операторы:
|
Поразрядный OR:
mysql> SELECT 29 | 15;
-> 31
Результат unsigned 64-bit integer.
&
Поразрядный AND:
mysql> SELECT 29 & 15;
-> 13
Результат unsigned 64-bit integer.
^
Поразрядный XOR:
mysql> SELECT 1 ^ 1;
-> 0
mysql> SELECT 1 ^ 0;
-> 1
mysql> SELECT 11 ^ 3;
-> 8
Результат unsigned 64-bit integer.
<<
Смещает longlong число (BIGINT
) влево.
mysql> SELECT 1 << 2;
-> 4
Результат unsigned 64-bit integer. Значение является усеченным к 64 битам.
В частности, если количество сдвига больше или равно ширине числа unsigned
64-bit, результатом будет 0.
>>
Смещает longlong число (BIGINT
) вправо.
mysql> SELECT 4 >> 2;
-> 1
Результат unsigned 64-bit integer. Значение является усеченным к 64 битам.
В частности, если количество сдвига больше или равно ширине числа unsigned
64-bit, результатом будет 0.
~
Инвертирует все биты.
mysql> SELECT 5 & ~1;
-> 4
Результат unsigned 64-bit integer.
BIT_COUNT(N
)
Возвращает число битов, которые установлены в параметре
N .
mysql> SELECT BIT_COUNT(29), BIT_COUNT(b'101010');
-> 4, 3
13.13. Функции шифрования и сжатия
Таблица 13.17. Функции шифрования и сжатия
Многие функции шифрования и сжатия возвращают строки в которых результат
мог бы содержать произвольные значения байта. Если Вы хотите сохранить эти
результаты, используйте столбец с типом двоичной строки
VARBINARY или
BLOB . Это позволит избежать
потенциальных проблем с удалением конечного пробела или преобразованием
набора символов, которое изменило бы значения данных, которые могут
произойти, если Вы используете недвоичной строковый тип данных
(CHAR ,
VARCHAR или
TEXT ).
Некоторое функции шифрования возвращают строки символов ASCII:
MD5() ,
PASSWORD() ,
SHA() ,
SHA1() ,
SHA2() .
Их возвращаемое значение - недвоичная строка, у которой есть набор символов
и сопоставление, определенные системными переменными
character_set_connection и
collation_connection .
Для ситуаций, в которых функции, подобные MD5() или
SHA1() , вернут строку шестнадцатеричных цифр как двоичную,
возвращаемое значение не может быть преобразовано в верхний регистр или
сравнено нечувствительным к регистру способом. Вы должны преобразовать
значение в недвоичную строку. См. обсуждение двоичного строкового
преобразования в разделе 13.10.
Если приложение хранит значения функции
MD5() или
SHA1() , которые
возвращают строку шестнадцатеричных цифр, более эффективное хранение и
сравнения могут быть получены, преобразовывая шестнадцатеричное
представление в двоичное, используя
UNHEX() и
сохраняя результат в столбце
BINARY(N ) .
Каждая пара шестнадцатеричных цифр требует одного байта в двоичной форме,
таким образом, значение N зависит от длины строки.
N 16 для
MD5() и 20 для
SHA1() . Для
SHA2()
N от 28 до 32в зависимости от параметра, определяющего
желаемую длину результата в битах.
Накладные расходы для хранения шестнадцатеричных строк в столбце
CHAR от 2 до 8 раз, если значение
сохранено в столбце, который использует набор символов
utf8 (где каждый символ использует 4 байта). Хранение строки
также приводит к более медленным сравнениям из-за больших значений и
потребности принять правила сопоставления набора символов во внимание.
Предположите, что приложение хранит значение
MD5() в столбце
CHAR(32) :
CREATE TABLE md5_tbl (md5_val CHAR(32), ...);
INSERT INTO md5_tbl (md5_val, ...) VALUES(MD5('abcdef'), ...);
Чтобы преобразовать строки в более компактную форму, измените приложение,
чтобы использовать UNHEX()
и BINARY(16) :
CREATE TABLE md5_tbl (md5_val BINARY(16), ...);
INSERT INTO md5_tbl (md5_val, ...) VALUES(UNHEX(MD5('abcdef')), ...);
Приложения должны быть подготовлены обработать очень редкий случай,
когда хеширующая функция производит то же самое значение для двух различных
входных значений. Один способ сделать обнаруживаемые столкновения состоит в
том, чтобы сделать столбец хеша первичным ключом.
Пароли или другие чувствительные значения, поставляемые как параметры
функциям шифрования, посылают открытым текстом серверу MySQL, если соединение
SSL не используется. Кроме того, такие значения появятся в любых журналах
MySQL. Чтобы избежать этих типов проблем, приложения могут зашифровать
чувствительные значения на стороне клиента прежде, чем послать их серверу. Те
же самые соображения относятся к ключам шифрования. Чтобы избежать выставлять
их, приложения могут использовать хранимые процедуры, чтобы зашифровать и
дешифровать значения на стороне сервера.
AES_DECRYPT(
crypt_str ,key_str [,
init_vector ])
Эта функция дешифрует данные, используя официальный алгоритм AES (Advanced
Encryption Standard).
Дополнительный векторный параметр инициализации
init_vector . Запросы, применяющие
AES_DECRYPT() ,
опасны для репликации на основе запросов и не могут быть
сохранены в кэше запроса.
AES_ENCRYPT(str
,key_str [,init_vector
])
AES_ENCRYPT() и
AES_DECRYPT()
реализуют шифрование и дешифрование данных, используя официальный алгоритм
AES (Advanced Encryption Standard), ранее известный как
Rijndael. Стандарт AES разрешает различные длины ключа. По
умолчанию эти функции осуществляют AES с 128-битной длиной ключа.
Длины ключа 196 или 256 битов могут использоваться, как описано позже.
Длина ключа компромисс между скоростью работы и безопасностью.
AES_ENCRYPT()
шифрует строку str с использованием ключевой строки
key_str и возвращает двоичную строку, содержащую
зашифрованный вывод.
AES_DECRYPT() дешифрует зашифрованную строку
crypt_str с использованием ключевой строки
key_str и возвращает оригинальную строку открытого
текста. Если любой функциональный параметр NULL ,
функция вернет NULL .
Параметры str и crypt_str
могут быть любой длины, дополнение автоматически добавлено к
str , чтобы это было кратным числом блоков,
как требуется основанными на блоке алгоритмами, такими как AES.
Это дополнение автоматически удалено
AES_DECRYPT() .
Длина crypt_str может быть вычислена,
используя эту формулу:
16 * (trunc(string_length / 16) + 1)
Для длины ключа 128 бит самый безопасный способ передать ключ в
key_str это создать действительно случайную 128-битную
последовательность и передать это как двоичное значение. Например:
INSERT INTO t VALUES (1,AES_ENCRYPT('text',
UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
Пароль может использоваться, чтобы произвести ключ AES,
хешируя пароль. Например:
INSERT INTO t VALUES (1,AES_ENCRYPT('text',
UNHEX(SHA2('My secret passphrase',512))));
Не передавайте пароль непосредственно к
crypt_str , хешируйте это сначала. Предыдущие версии
этой документации предложили прежний подход, но это больше не рекомендуется,
поскольку примеры, показанные здесь, более безопасны.
Если AES_DECRYPT()
обнаруживает недопустимые данные или неправильное дополнение, она
возвращает NULL . Однако, возможно для
AES_DECRYPT()
возвратить не NULL , если входные данные или ключ недопустимы.
AES_ENCRYPT() и
AES_DECRYPT()
допускают управление режимом блочного шифрования и берут дополнительный
векторный параметр инициализации init_vector :
Системная переменная
block_encryption_mode
управляет режимом для основанных на блоке алгоритмов шифрования.
Ее значение по умолчанию aes-128-ecb , которое показывает
шифрование, используя длину ключа 128 битов и режим ECB. Для описания
разрешенных значений этой переменной см.
раздел 6.1.5.
- Дополнительный параметр
init_vector
обеспечивает вектор инициализации для режимов блочного шифрования,
которые требуют этого.
Для режимов, которые требуют дополнительного параметра
init_vector , это должны быть 16 байт или больше (байты
сверх 16 проигнорированы). Ошибка происходит, если
init_vector отсутствует.
Для режимов, которые не требуют init_vector , это
проигнорировано, и предупреждение произведено, если это определено.
Случайная строка байт, чтобы использовать для вектора инициализации, может
быть произведена вызовом
RANDOM_BYTES(16) .
Для режимов шифрования, которые требуют вектор инициализации, тот же самый
вектор должен использоваться для шифрования и дешифрования.
mysql> SET block_encryption_mode = 'aes-256-cbc';
mysql> SET @key_str = SHA2('My secret passphrase',512);
mysql> SET @init_vector = RANDOM_BYTES(16);
mysql> SET @crypt_str = AES_ENCRYPT('text',@key_str,@init_vector);
mysql> SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector);
+-----------------------------------------------+
| AES_DECRYPT(@crypt_str,@key_str,@init_vector) |
+-----------------------------------------------+
| text |
+-----------------------------------------------+
Следующая таблица приводит каждый разрешенный режим блочного шифрования,
библиотеки SSL, которые поддерживают это, и требуется ли
векторный параметр инициализации.
Режим блочного шифрования |
Поддерживается библиотеками SSL |
Нужен ли вектор инициализации? |
ECB | OpenSSL, yaSSL | Нет |
CBC | OpenSSL, yaSSL | Да |
CFB1 | OpenSSL | Да |
CFB8 | OpenSSL | Да |
CFB128 | OpenSSL | Да |
OFB | OpenSSL | Да |
Запросы, использующие
AES_ENCRYPT() или
AES_DECRYPT()
опасны для основанной на запросах репликации и не могут быть
сохранены в кэше запроса.
COMPRESS(
string_to_compress )
Сжимает строку и возвращает результат как двоичную строку.
Эта функция требует, чтобы MySQL был собран с библиотекой сжатия такой, как
zlib . Иначе, возвращаемое значение всегда NULL .
Сжатая строка может быть расжата
UNCOMPRESS() .
mysql> SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
-> 21
mysql> SELECT LENGTH(COMPRESS(''));
-> 0
mysql> SELECT LENGTH(COMPRESS('a'));
-> 13
mysql> SELECT LENGTH(COMPRESS(REPEAT('a',16)));
-> 15
Сжатое строковое содержание сохранено следующим путем:
DECODE(crypt_str
,pass_str )
DECODE()
дешифрует зашифрованную строку crypt_str с
использованием pass_str как пароля.
crypt_str должна быть строкой, возвращенной из
ENCODE() .
Функции ENCODE() и
DECODE() устарели в
MySQL 8.0, будут удалены в будущем выпуске MySQL и больше не должны
использоваться. Рассмотрите использование вместо них
AES_ENCRYPT() и
AES_DECRYPT() .
DES_DECRYPT(
crypt_str [,key_str ])
Дешифрует строку, зашифрованную с помощью
DES_ENCRYPT() .
Если ошибка происходит, эта функция возвращает NULL .
Эта функция работает, только если MySQL был сконфигурирован с поддержкой
SSL. См. раздел 7.4.
Если нет параметра key_str ,
DES_DECRYPT()
исследует первый байт зашифрованной строки, чтобы определить ключевое число
DES, которое использовалось, чтобы зашифровать оригинальную строку, затем
читает ключ из ключевого файла DES, чтобы дешифровать сообщение. Для того,
чтобы работать, пользователь должен иметь привилегию
SUPER .
Ключевой файл может быть определен с помощью опции сервера
--des-key-file
.
Если Вы передаете этой функции параметр key_str ,
эта строка используется в качестве ключа, чтобы дешифровать сообщение.
Если параметр crypt_str не зашифрованная строка,
MySQL возвращает crypt_str .
Функции DES_ENCRYPT()
и DES_DECRYPT()
устарели, будут удалены в будущем выпуске MySQL и больше не
должны использоваться. Рассмотрите использование вместо них
AES_ENCRYPT() и
AES_DECRYPT() .
DES_ENCRYPT(str
[,{key_num |key_str }])
Шифрует строку с данным ключом, используя алгоритм Triple-DES.
Эта функция работает, только если MySQL был сконфигурирован с поддержкой
SSL. См. раздел 7.4.
Ключ шифрования выбирается на основании второго параметра
DES_ENCRYPT() ,
если он задан. Без параметра используется первый ключ из ключевого файла
DES. С параметром key_num данное ключевое число (от 0
до 9) из ключевого файла DES используется. С параметром
key_str данная ключевая строка используется,
чтобы зашифровать str .
Ключевой файл может быть определен с помощью опции сервера
--des-key-file
.
Строка возвращения двоичная строка, где первый символ
CHAR(128 | key_num
) . Если ошибка происходит,
DES_ENCRYPT()
вернет NULL .
Эти 128 добавлены, чтобы облегчить распознавание зашифрованного ключа.
Если Вы используете строковый ключ, key_num 127.
Строковая длина для результата дана этой формулой:
new_len = orig_len +
(8-(orig_len % 8))+1
У каждой строки в ключевом файле DES есть следующий формат:
key_num des_key_str
Каждое значение key_num должно быть числом в
диапазоне от 0 до 9 . Строки в файле могут быть в
любом порядке. des_key_str строка, которая
используется, чтобы зашифровать сообщение. Должен быть по крайней мере один
пробел между числом и ключом. Первый ключ задает значение по умолчанию,
которое используется, если Вы не определяете ключевого параметра
DES_ENCRYPT() .
Вы можете сказать MySQL читать новые значения ключа из ключевого файла
запросом FLUSH DES_KEY_FILE . Это
требует привилегию RELOAD
.
Одна выгода наличия ряда ключей по умолчанию то, что это дает приложениям
способ проверить существование зашифрованных значений столбцов, не давая
конечному пользователю право дешифровать эти значения.
Функции DES_ENCRYPT()
и DES_DECRYPT()
устарели будут удалены в будущем выпуске MySQL и больше не должны
использоваться. Рассмотрите использование вместо них
AES_ENCRYPT() и
AES_DECRYPT() .
mysql> SELECT customer_address FROM customer_table
> WHERE crypted_credit_card = DES_ENCRYPT('credit_card_number');
ENCODE(str ,
pass_str )
ENCODE() шифрует
str с использованием
pass_str как пароля. Результат двоичная строка той же
самой длины, что и str . Чтобы дешифровать результат,
надо использовать DECODE()
.
Функции ENCODE() и
DECODE() устарели в
MySQL 8.0 будут удалены в будущем выпуске MySQL и больше
не должны использоваться.
Если Вы все еще должны использовать
ENCODE() ,
значение salt должно использоваться с ней, чтобы уменьшить риск. Например:
ENCODE('cleartext', CONCAT('my_random_salt','my_secret_password'))
Новое случайное значение должно использоваться всякий раз,
когда пароль обновлен.
ENCRYPT(str [,
salt ])
Шифрует str с использование системного вызова Unix
crypt() и возвращает двоичную строку. Параметр
salt должен быть строкой по крайней мере с двумя
символами, или результат будет NULL . Если нет параметра
salt , случайное значение используется.
Функция ENCRYPT()
устарела будет удалена в будущем выпуске MySQL и больше не должна
использоваться. Рассмотрите использование вместо нее
AES_ENCRYPT() .
mysql> SELECT ENCRYPT('hello');
-> 'VxuFAJXVARROc'
ENCRYPT()
игнорирует все кроме первых восьми символов str ,
по крайней мере, на некоторых системах. Это поведение определено выполнением
основного системного вызова crypt() .
Использование ENCRYPT()
с многобайтовыми наборами символов ucs2 ,
utf16 , utf16le или utf32 не
рекомендуются, потому что системный вызов ожидает строку,
законченную нулевым байтом.
Если crypt() не доступно на Вашей системе (как имеет место в
Windows), ENCRYPT()
всегда возвращает NULL .
MD5(str )
Вычисляет 128-битную контрольную сумму MD5 для строки. Значение возвращено
как строка из 32 шестнадцатеричных цифр или NULL , если параметр
был NULL . Возвращаемое значение может, например, использоваться
в качестве ключа хеша. См. примечания в начале этого раздела о хранении
значений хеша эффективно.
Возвращаемое значение недвоичная строка в наборе символов соединения.
mysql> SELECT MD5('testing');
-> 'ae2b1fca515949e5d54fb22b8ed95575'
Это RSA Data Security, Inc. MD5 Message-Digest Algorithm.
PASSWORD(str
)
Эта функция устарела и будет удалена в будущем выпуске MySQL.
Возвращает хешированную строку пароля, вычисленную из пароля открытого
текста str . Возвращаемое значение недвоичная строка в
наборе символов соединения или NULL , если параметр
NULL . Эта функция интерфейс SQL к алгоритму, используемому
сервером, чтобы зашифровать пароли MySQL для хранения в
таблице mysql.user .
Переменная old_passwords
управляет методом хеширования пароля, используемым функцией
PASSWORD() .
Это также влияет на пароль, выполненный
CREATE USER и
GRANT , которые определяют пароль,
используя пункт IDENTIFIED BY .
Следующая таблица показывает разрешенные значения
old_passwords ,
метод хеширования пароля для каждого значения и какие плагины аутентификации
используют пароли, хешированные каждым методом.
Значение | Метод хэширования
| Связанный плагин аутентификации |
0 | MySQL 4.1 native hashing |
mysql_native_password |
2 | SHA-256 hashing |
sha256_password |
SHA-256 password hashing
(old_passwords=2 )
использует случайное значение salt, которое делает результат
PASSWORD()
недетерминированным. Следовательно, запросы, которые используют эту функцию,
небезопасны для основанной на запросах репликации и не могут быть
сохранены в кэше запроса.
Шифрование, выполненное
PASSWORD() ,
однонаправленное. Это не тот же самый тип шифрования, используемого для
паролей Unix, для него надо использовать
ENCRYPT() .
PASSWORD()
используется системой аутентификации в сервере MySQL, Вы не должны
not использовать это в своих собственных приложениях. С
этой целью рассмотрите
MD5() или
SHA2() . Также см.
RFC 2195,
section 2 (Challenge-Response Authentication Mechanism (CRAM)).
При некоторых обстоятельствах, запросы, которые вызывают
PASSWORD()
могут быть зарегистрированы в журналах сервера или на стороне клиента в файле
истории, например, ~/.mysql_history ,
что означает, что пароли открытого текста могут быть считаны любым имеющим
доступ к той информации. Для информации об условиях, при которых это
происходит для журналов сервера и как управлять ею, см.
раздел 7.1.2.3.
RANDOM_BYTES(len
)
Эта функция возвращает двоичную строку из
len случайных байт из
генератора случайных чисел библиотеки SSL (OpenSSL или yaSSL). Разрешенные
значения len от 1 до 1024. Для значений вне диапазона
RANDOM_BYTES()
производит предупреждение и возвращает NULL .
RANDOM_BYTES()
может использоваться, чтобы обеспечить вектор инициализации для
AES_DECRYPT() и
AES_ENCRYPT() .
Для использования в этом контексте len должен быть по
крайней мере 16. Большие значения разрешены, но
байты сверх 16 проигнорированы.
RANDOM_BYTES()
производит случайное значение, которое делает его результат
недетерминированным. Следовательно, запросы, которые используют эту функцию,
опасны для основанной на запросах репликации и не могут быть
сохранены в кэше запроса.
SHA1(str )
, SHA(str
)
Вычисляет 160-битовую контрольную сумму SHA-1 для строки, как описано в
RFC 3174 (безопасный алгоритм хеша). Значение возвращено как строка из 40
шестнадцатеричных цифр или NULL , если параметр был
NULL . Одно из возможных применений для этой функции как ключ
хеша. См. примечания в начале этого раздела о хранении значений хеша
эффективно. Вы можете также использовать
SHA1()
как шифровальную функция для того, чтобы сохранить пароли.
SHA() синоним для
SHA1() .
Возвращаемое значение недвоичная строка в наборе символов соединения.
mysql> SELECT SHA1('abc');
-> 'a9993e364706816aba3e25717850c26c9cd0d89d'
SHA1()
может считаться более безопасным эквивалентом
MD5() .
SHA2(str ,
hash_length )
Вычисляет семейство функций хеша SHA-2 (SHA-224, SHA-256, SHA-384 и
SHA-512). Первый параметр строка открытого текста, которая будет хеширована.
Второй параметр указывает на желаемую длину в битах результата, у него
должно быть значение 224, 256, 384, 512 или 0 (эквивалентен 256).
Если любой параметр NULL или длина хеша не одно из разрешенных
значений, возвращаемое значение NULL . Иначе функциональный
результат значение хеша, содержащее желаемое число битов.
Возвращаемое значение недвоичная строка в наборе символов соединения.
mysql> SELECT SHA2('abc', 224);
-> '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'
Эта функция работает, только если MySQL был сконфигурирован с поддержкой
SSL. См. раздел 7.4.
SHA2()
более надежна криптографически, чем
MD5() или
SHA1() .
UNCOMPRESS(
string_to_uncompress )
Разжимает строку, сжатую
COMPRESS() .
Если параметр не сжатое значение, результат NULL . Эта функция
требует, чтобы MySQL был собран с библиотекой сжатия такой, как
zlib . Иначе возвращаемое значение всегда NULL .
mysql> SELECT UNCOMPRESS(COMPRESS('any string'));
-> 'any string'
mysql> SELECT UNCOMPRESS('any string');
-> NULL
UNCOMPRESSED_LENGTH(compressed_string )
Возвращает длину, которую сжатая строка имела прежде, чем быть сжатой.
mysql> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
-> 30
VALIDATE_PASSWORD_STRENGTH(str )
Учитывая параметр, представляющий пароль открытого текста, эта функция
возвращает целое число, чтобы указать, насколько сильный пароль.
Возвращаемое значение колеблется от 0 (слабый) до 100 (сильный).
Оценка пароля
VALIDATE_PASSWORD_STRENGTH() сделана плагином
validate_password . Если плагин не установлен, функция всегда
возвращает 0. Для информации об установке плагина validate_password
см. раздел 7.5.2
. Чтобы исследовать или сконфигурировать параметры, которые затрагивают
тестирование пароля, проверьте или установите системные переменные,
осуществленные плагином validate_password . См.
раздел 7.5.2.2.
Пароль подвергнут все более и более строгим тестам, и возвращаемое
значение показывает, какие тесты были удовлетворены, как показано в следующей
таблице. Кроме того, если переменная
validate_password_check_user_name включена, и пароль соответствует
имени пользователя,
VALIDATE_PASSWORD_STRENGTH() возвращает 0, независимо от
настроек других переменных validate_password .
Тест пароля | Возвращаемое
значение |
Длина < 4 | 0 |
Длина = 4 и <
validate_password_length | 25 |
Удовлетворяет политике 1 (LOW ) |
50 |
Удовлетворяет политике 2 (MEDIUM ) |
75 |
Удовлетворяет политике 3 (STRONG ) |
100 |
13.14. Информационные функции
Таблица 13.18. Информационные функции
BENCHMARK(count
,expr )
Функция BENCHMARK()
выполняет выражение expr count
раз. Это может использоваться, чтобы оценить, как быстро MySQL
обрабатывает выражение. Значение результата всегда 0 .
Намеченное использование в клиенте
mysql,
который сообщает о времени выполнения запроса:
mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
1 row in set (4.74 sec)
Время показывает прошедшее время на клиенте, а не время центрального
процессора на сервере. Желательно выполнить
BENCHMARK() несколько
раз и интерпретировать результат относительно того, как загржен сервер.
BENCHMARK()
предназначена для того, чтобы определить эксплуатационные качества во время
выполнения скалярных выражений, у которых есть некоторые существенные
значения для способа, которым Вы используете их и интерпретируете результаты:
Только скалярные выражения могут использоваться. Хотя выражение
может быть подзапросом, оно должно возвратить единственный столбец и самое
большее единственную строку. Например,
BENCHMARK(10, (SELECT * FROM
t)) потерпит неудачу, если таблица t
имеет больше, чем один столбец или больше, чем одну строку.
- Выполнение
SELECT expr
N раз отличается от выполнения
SELECT BENCHMARK(N , expr )
с точки зрения количества вовлеченных ресурсов. У этих двух запросов
есть совсем другие профили выполнения, и Вы не должны ожидать, что они займут
то же самое количество времени. В первом случае работают оптимизатор,
анализатор, блокировка таблиц, причем все это работает каждый из
N раз. Во втором случае структуры памяти, локальное
кэширование и оптимизация отрабатывают только однажды, после чего
N раз оценивается только само выражение.
Результаты BENCHMARK()
определяют эксплуатационные качества компонента во время выполнения,
давая больше веса тому компоненту и удаляя шум, внесенный сетью,
оптимизатором, анализатором и другими компонентами.
CHARSET(str )
Возвращает набор символов строкового параметра.
mysql> SELECT CHARSET('abc');
-> 'latin1'
mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
-> 'utf8'
mysql> SELECT CHARSET(USER());
-> 'utf8'
COERCIBILITY(str
)
Возвращает сопоставление строкового параметра.
mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
-> 0
mysql> SELECT COERCIBILITY(USER());
-> 3
mysql> SELECT COERCIBILITY('abc');
-> 4
Возвращаемые значения расшифрованы в следующей таблице. У меньших значений
есть более высокий приоритет.
Значение | Смысл |
Пример |
0 | Явное сопоставление |
Значение с COLLATE |
1 | Никакого сопоставления |
Связь строк с различными сопоставлениями |
2 | Неявное сопоставление |
Значение столбца, параметр сохраненной процедуры или локальная переменная
|
3 | Постоянная системы |
Возвращаемое значение USER()
|
4 | Сопоставление |
Буквальная строка |
5 | Игнорируемое |
NULL или выражение произошло из NULL |
COLLATION(str
)
Возвращает сопоставление строкового параметра.
mysql> SELECT COLLATION('abc');
-> 'latin1_swedish_ci'
mysql> SELECT COLLATION(_utf8'abc');
-> 'utf8_general_ci'
CONNECTION_ID()
Возвращает ID соединения (ID потока). У каждого соединения есть ID,
который уникален среди группы в настоящее время присоединенных клиентов.
Значение, возвращенное
CONNECTION_ID() ,
то же самое, как в столбце ID таблицы
INFORMATION_SCHEMA.PROCESSLIST
, столбце Id вывода
SHOW PROCESSLIST и
столбце PROCESSLIST_ID таблицы
threads
в Performance Schema.
mysql> SELECT CONNECTION_ID();
-> 23786
CURRENT_ROLE()
Возвращает двоичную строку, содержащую текущие активные роли для текущего
сеанса, отделенного запятыми или NONE , если нет ролей.
Предположите, что учетной записи предоставляют роли следующим образом:
GRANT 'r1', 'r2' TO 'u1'@'localhost';
В сеансах для u1 стартовое значение CURRENT_USER()
роль учетной записи по умолчанию или роли. Используя
SET ROLE можно менять:
mysql> SET ROLE ALL; SELECT CURRENT_ROLE();
+-------------------+
| CURRENT_ROLE() |
+-------------------+
| `r1`@`%`,`r2`@`%` |
+-------------------+
mysql> SET ROLE 'r1'; SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| `r1`@`%` |
+----------------+
CURRENT_USER ,
CURRENT_USER()
Возвращает имя пользователя и комбинацию имени хоста для учетной записи
MySQL. Эта учетная запись определяет Ваши привилегии доступа. Возвращаемое
значение строка в наборе символов utf8 .
Значение CURRENT_USER()
может отличаться от значения
USER() .
mysql> SELECT USER();
-> 'davida@localhost'
mysql> SELECT * FROM mysql.user;
ERROR 1044: Access denied for user ''@'localhost' to
database 'mysql'
mysql> SELECT CURRENT_USER();
-> '@localhost'
Пример иллюстрирует это: хотя клиент определил имя пользователя
davida (как обозначено значением функции
USER() ),
сервер подтверждает подлинность клиента, использующего анонимную учетную
запись пользователя (как обозначено пустой частью имени пользователя в
значении CURRENT_USER()
).
В пределах сохраненной программы или представления
CURRENT_USER()
возвращает пользователя, который определил объект (как дано значением
DEFINER ), если не определено с параметром
SQL SECURITY INVOKER . В последнем случае
CURRENT_USER()
возвращает того, кто вызвал обхект.
У триггеров и событий нет никакой опции, чтобы определить SQL
SECURITY , таким образом, для этих объектов
CURRENT_USER()
возвращает пользователя, который определил объект. Чтобы возвратить
вызвашего, надо использовать USER()
или
SESSION_USER() .
Следующие запросы поддерживают использование
CURRENT_USER() ,
чтобы взять имя (возможно, и хост) текущего пользователя или определителя,
в таких случаях
CURRENT_USER() расширен как и где необходимо:
Для информации о значениях, что это расширение
CURRENT_USER()
имеет для репликации в различных выпусках MySQL 8.0 см.
see раздел 19.4.1.8
.
DATABASE()
Возвращает значение по умолчанию имени базы данных как строка в
utf8 . Если нет никакой базы данных по умолчанию,
DATABASE() вернет
NULL . В пределах сохраненной процедуры база данных
по умолчанию это база данных, с которой связана процедура, который не
обязательно является той же самой базой данных, которая значение по
умолчанию в контексте запроса.
mysql> SELECT DATABASE();
-> 'test'
Если нет никакой базы данных по умолчанию,
DATABASE() вернет
NULL .
FOUND_ROWS()
Запрос SELECT может включать
пункт LIMIT , чтобы ограничить число строк, которые сервер
возвращает клиенту. В некоторых случаях желательно знать, сколько строк
запрос возвратил бы без LIMIT , но не выполняя запрос снова.
Чтобы получить это количество строк, включите опцию
SQL_CALC_FOUND_ROWS в
SELECT и затем вызовите
FOUND_ROWS() позже:
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
Второй SELECT возвращает число,
указывающее сколько строк первый
SELECT
возвратил бы без LIMIT .
В отсутствие опции SQL_CALC_FOUND_ROWS и наличии успешного
SELECT
FOUND_ROWS()
возвращает число строк в наборе результатов, возвращенном этим запросом. Если
запрос включает LIMIT ,
FOUND_ROWS()
возвращает число строк до limit. Например,
FOUND_ROWS()
возвращает 10 или 60, соответственно, если запрос включает
respectively, if the statement includes LIMIT 10 или
LIMIT 50, 10 .
Количество строк, доступное через
FOUND_ROWS()
является переходным и не предназначено быть доступным после
SELECT SQL_CALC_FOUND_ROWS .
Если Вы должны обратиться к значению позже, сохраните его:
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql> SET @rows = FOUND_ROWS();
Если Вы используете SELECT SQL_CALC_FOUND_ROWS , MySQL
должен вычислить, сколько строк находится в полном наборе результатов.
Однако, это быстрее, чем выполнение запроса снова без LIMIT ,
потому что набор результатов не надо посылать клиенту.
SQL_CALC_FOUND_ROWS и
FOUND_ROWS()
могут быть полезными в ситуациях, когда Вы хотите ограничить число строк,
которые возвращает запрос, но также и определить число строк в полном наборе
результатов, не выполняя запрос снова. Пример: Веб-сценарий, который
представляет пронумерованные страницы, содержащие ссылки к страницам, которые
показывают другие разделы результата поиска. Использование
FOUND_ROWS()
позволяет Вам определить, сколько других страниц необходимо для
остальной части результата.
Использование SQL_CALC_FOUND_ROWS и
FOUND_ROWS()
более сложно для for UNION , чем для
простого SELECT , поскольку
LIMIT может произойти в многих местах в
UNION . Это может быть применено к
отдельному запросу SELECT в
UNION или глобально к результату
UNION в целом.
Смысл SQL_CALC_FOUND_ROWS для
UNION в том, что
это должно возвратить количество строк, которое было бы возвращено без
глобального LIMIT . Условия для использования
SQL_CALC_FOUND_ROWS с
UNION :
Вне случаев, описанных здесь, поведение
FOUND_ROWS()
не определено (например, его значение после запроса
SELECT , который
терпит неудачу с ошибкой).
FOUND_ROWS()
не копируется, достоверно используя основанную на запросах репликацию. Эта
функция автоматически копируется, используя основанную на строках репликацию.
LAST_INSERT_ID()
, LAST_INSERT_ID(
expr )
Без параметра
LAST_INSERT_ID() вернет BIGINT UNSIGNED (64-bit)
число, представляющее первое автоматически произведенное значение, успешно
вставленное для столбца AUTO_INCREMENT в результате выполненного
последним запроса INSERT .
Значение LAST_INSERT_ID()
остается неизменным, если никакие строки успешно не вставлены.
С параметром
LAST_INSERT_ID() возвращает unsigned integer.
Например, после вставки строки, которая производит значение
AUTO_INCREMENT , Вы можете получить значение так:
mysql> SELECT LAST_INSERT_ID();
-> 195
В настоящее время выполняющийся запрос не затрагивает значение
LAST_INSERT_ID()
. Предположите, что Вы производите значение AUTO_INCREMENT
с одним запросом, а затем обращаетесь к
LAST_INSERT_ID()
при вставке нескольих строк INSERT ,
которое вставляет строки в таблицу с его собственным столбцом
AUTO_INCREMENT . Значение
LAST_INSERT_ID()
останется устойчивым во втором запросе: его значение для второй и более
поздних строк не затронуто более ранними вставками строки. Однако, если Вы
смешиваете ссылки на
LAST_INSERT_ID()
и LAST_INSERT_ID(
expr ) , эффект неопределен.
Если предыдущий запрос возвратил ошибку, значение
LAST_INSERT_ID()
не определено. Для транзакционных таблиц, если запрос откатился из-за ошибки,
значение LAST_INSERT_ID()
не определено. Для ручного
ROLLBACK значение
LAST_INSERT_ID()
не восстановлен к тому, что было перед транзакцией, это остается, как было в
точке ROLLBACK .
В пределах тела сохраненной процедуры, функции или триггера, значение
LAST_INSERT_ID()
изменяется тем же самым путем, что касается запросов, выполненных вне этих
видов объектов. Эффект сохраненной процедуры или триггера на значение
LAST_INSERT_ID() ,
зависит от вида процедуры:
Если хранимая процедура выполняет запросы, которые изменяют
значение LAST_INSERT_ID()
, измененное значение замечено запросами, которые следуют
за вызовом процедуры.
- Для сохраненных функций и триггеров, которые изменяют значение,
восстановлено значение, когда функция или триггера завершилась, так
последующие запросы не будут видеть измененное значение.
ID, который был произведен, поддержан в сервере на основе соединения.
Это означает, что значение, возвращенное функцией данному клиенту, является
первым значением AUTO_INCREMENT , произведенным для нового
запроса, затрагивающего столбец AUTO_INCREMENT этим
клиентом. Это значение не может быть затронуто другими клиентами,
даже если они производят свои значения AUTO_INCREMENT .
Это поведение гарантирует, что каждый клиент может получить его собственный
ID без беспокойства о деятельности других клиентов, и без потребности в
блокировках или транзакциях.
Значение
LAST_INSERT_ID() не изменено, если Вы устанавливаете столбец
AUTO_INCREMENT строки в значение, которое не является
NULL или 0 .
Если Вы вставляете много строк, используя одиночный
INSERT ,
LAST_INSERT_ID()
возвращает значение, произведенное для первой
вставленной строки. Причина этого состоит в том, чтобы позволить легко
воспроизвести тот же самый INSERT
для другого сервера.
Например:
mysql> USE test;
Database changed
mysql> CREATE TABLE t (
-> id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> name VARCHAR(10) NOT NULL);
Query OK, 0 rows affected (0.09 sec)
mysql> INSERT INTO t VALUES (NULL, 'Bob');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
| 1 | Bob |
+----+------+
1 row in set (0.01 sec)
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO t VALUES
-> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Mary |
| 3 | Jane |
| 4 | Lisa |
+----+------+
4 rows in set (0.01 sec)
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
Хотя второй запрос INSERT
вставил три новых строки в t , ID, произведенный для первой из
этих строк, был 2 , и именно это значение возвращено
LAST_INSERT_ID()
для следующего SELECT .
Если Вы используете INSERT
IGNORE и строка проигнорирована,
LAST_INSERT_ID()
остается неизменным (или 0 возвращен, если соединение еще не выполнило
успешно INSERT ) и, для нетранзакционных таблиц, счетчик
AUTO_INCREMENT не увеличен. Для таблиц InnoDB
счетчик AUTO_INCREMENT увеличен, если
innodb_autoinc_lock_mode установлена в
1 или 2 :
mysql> USE test;
Database changed
mysql> SELECT @@innodb_autoinc_lock_mode;
+----------------------------+
| @@innodb_autoinc_lock_mode |
+----------------------------+
| 1 |
+----------------------------+
1 row in set (0.00 sec)
mysql> CREATE TABLE `t` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`val` INT(11) DEFAULT NULL, PRIMARY KEY (`id`),
UNIQUE KEY `i1` (`val`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.02 sec)
-- Insert two rows
mysql> INSERT INTO t (val) VALUES (1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
-- With auto_increment_offset=1, the inserted rows
-- result in an AUTO_INCREMENT value of 3
mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val` int(11) DEFAULT NULL, PRIMARY KEY (`id`),
UNIQUE KEY `i1` (`val`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
-- LAST_INSERT_ID() returns the first automatically generated
-- value that is successfully inserted for the AUTO_INCREMENT column
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
-- The attempted insertion of duplicate rows fail but errors are ignored
mysql> INSERT IGNORE INTO t (val) VALUES (1),(2);
Query OK, 0 rows affected (0.00 sec)
Records: 2 Duplicates: 2 Warnings: 0
-- With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter
-- is incremented for the ignored rows
mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val` int(11) DEFAULT NULL, PRIMARY KEY (`id`),
UNIQUE KEY `i1` (`val`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
-- The LAST_INSERT_ID is unchanged becuase the previous insert was unsuccessful
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
Если expr дан как параметр
LAST_INSERT_ID()
, значение параметра возвращено функцией и помнится как следующее
значение, которое будет возвращено
LAST_INSERT_ID()
. Это может использоваться, чтобы моделировать последовательности:
Составьте таблицу, чтобы сохранить
последовательность и инициализируйте это:
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
- Используйте таблицу, чтобы произвести порядковые номера:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();
UPDATE постепенно увеличивает
счетчик последовательности и вызывает следующий вызов
LAST_INSERT_ID()
, чтобы возвратить обновленное значение. Запрос
SELECT получает это значение.
Функция C API mysql_insert_id()
может также использоваться, чтобы получить значение. См.
раздел 25.8.7.38.
Отметьте, что
mysql_insert_id() обновлен только после
INSERT и
UPDATE ,
таким образом, Вы не можете использовать функцию C API, чтобы получить
значение для
LAST_INSERT_ID(expr ) после выполнения других
запросов SQL, подобных
SELECT или
SET .
ROLES_GRAPHML()
Возвращает двоичную строку, содержащую документ GraphML, представляющий
ролевые подграфики памяти.
ROW_COUNT()
ROW_COUNT() возвращает значение следующим образом:
Для UPDATE значение затронутых
строк по умолчанию число строк, фактически измененных. Если Вы определяете
флаг CLIENT_FOUND_ROWS для
mysql_real_connect()
соединяясь с mysqld
, значение затронутых строк число найденных строк, то есть,
соответствующее предложение WHERE .
Для REPLACE значение затронутых
строк 2, если новая строка заменяла старую строку, потому что в этом случае
одна строка была вставлена после того, как дубликат был удален.
Для INSERT
... ON DUPLICATE KEY UPDATE значение затронутых строк для каждой
строки 1, если строка вставлена как новая строка, 2, если существующая строка
обновлена, и 0, если существующая строка установлена в ее текущее
состояние. Если Вы определяете флаг CLIENT_FOUND_ROWS ,
значение затронутых строк 1 (не 0), если существующая строка установлена в
ее текущее состояние.
Значение ROW_COUNT()
подобно значению функции C API
mysql_affected_rows()
и количеству строк, которое выводит на экран клиент
mysql.
mysql> INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
| 3 |
+-------------+
1 row in set (0.00 sec)
mysql> DELETE FROM t WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec)
mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)
ROW_COUNT()
не копируется достоверно, используя основанную на запросе репликацию. Эта
функция автоматически копируется, используя основанную на строке репликацию.
SCHEMA()
Синоним для DATABASE()
.
SESSION_USER()
SESSION_USER()
синоним для USER() .
SYSTEM_USER()
SYSTEM_USER()
синоним для USER() .
USER()
Возвращает текущее имя пользователя MySQL и имя хоста
как строку в utf8 .
mysql> SELECT USER();
-> 'davida@localhost'
Значение указывает на имя пользователя, которое Вы определили, соединяясь
с сервером, и хост клиента, с которого Вы соединялись. Значение может
отличаться от значения из
CURRENT_USER() .
VERSION()
Возвращает строку, которая указывает на версию сервера MySQL.
Строка использует utf8 . У значения может быть суффикс в
дополнение к номеру версии. См. описание системной переменной
version в
разделе 6.1.5.
Эта функция опасна для основанной на запросах репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
установлена в STATEMENT .
mysql> SELECT VERSION();
-> '8.0.1-standard'
13.15.
Пространственные аналитические функции
MySQL обеспечивает функции, чтобы выполнить различные операции на
пространственных данных. Эти функции могут быть сгруппированы в несколько
главных категорий согласно типу работы, которую они выполняют:
Для общего обзора о поддержке MySQL использования пространственных данных
см. раздел 12.5.
13.15.1.
Обзор пространственных функций
Следующая таблица приводит каждую пространственную функцию и обеспечивает
краткое описание каждой.
Таблица 13.19. Пространственные функции
Имя | Описание |
GeometryCollection() |
Создает набор геометрии из конфигураций |
LineString() | Создает LineString из значений Point
|
MBRContains() | Содержит ли MBR одной геометрии MBR другой
|
MBRCoveredBy() | Покрыт ли один MBR другим |
MBRCovers()
| Покрывает ли один MBR другого |
MBRDisjoint() | Являются ли MBR двух конфигураций несвязными
|
MBREquals()
| Равны ли MBR двух конфигураций |
MBRIntersects() | Пересекаются ли MBR двух конфигураций
|
MBROverlaps() | Есть ли перекрытие у двух MBR |
MBRTouches() | Есть ли касание у двух MBR |
MBRWithin()
| Находится ли MBR одной геометрии в пределах MBR другой
|
MultiLineString() | Собирает MultiLineString из LineString
|
MultiPoint() | Собирает MultiPoint из Point |
MultiPolygon() | Собирает MultiPolygon из Polygon |
Point()
| Собирает Point из координат |
Polygon()
| Собирает Polygon из LineString |
ST_Area()
| Вернет область Polygon или MultiPolygon |
ST_AsBinary() , ST_AsWKB() |
Переходит от внутренней геометрии к WKB |
ST_AsGeoJSON() | Генерирует объект GeoJSON |
ST_AsText()
, ST_AsWKT() | Переходит от внутренней
геометрии к WKT |
ST_Buffer()
| Возвратит геометрию точек в пределах данного
расстояния от геометрии |
ST_Buffer_Strategy() | Произведет опцию стратегии для
ST_Buffer() |
ST_Centroid() | Вернет центр как точку |
ST_Contains() | Содержит ли одна геометрия другую |
ST_ConvexHull() | Возвратит выпуклый корпус геометрии |
ST_Crosses() | Пересекает ли одна геометрия другую |
ST_Difference() | Возвратит различие в наборе
точек двух конфигураций |
ST_Dimension() | Измерение геометрии |
ST_Disjoint() | Является ли одна
геометрия несвязной с другой |
ST_Distance() | Расстояние одной геометрии от другой |
ST_Distance_Sphere() | Минимальное расстояние на земле
между двумя конфигурациями |
ST_EndPoint() | Конечный Point LineString |
ST_Envelope() | MBR геометрии |
ST_Equals()
| Равна ли одна геометрия другой |
ST_ExteriorRing() | Возвратит внешнее кольцо Polygon |
ST_GeoHash() | Произведит значение geohash |
ST_GeomCollFromText() , ST_GeometryCollectionFromText() ,
ST_GeomCollFromTxt() | Набор геометрии из WKT |
ST_GeomCollFromWKB() , ST_GeometryCollectionFromWKB()
| Набор геометрии из WKB |
ST_GeometryN() | Возвратит N-ую геометрию
из набора геометрий |
ST_GeometryType() | Возвратит название типа геометрии |
ST_GeomFromGeoJSON() | Произведет геометрию из объекта
GeoJSON |
ST_GeomFromText() , ST_GeometryFromText() |
Набор геометрии из WKT |
ST_GeomFromWKB() , ST_GeometryFromWKB() |
Набор геометрии из WKB |
ST_InteriorRingN() | Вернет N-ое внутреннее кольцо Polygon
|
ST_Intersection() |
Пересечение набора точек двух конфигураций |
ST_Intersects() | Пересекает ли одна геометрия другую
|
ST_IsClosed() | Закрыта ли геометрия и проста |
ST_IsEmpty() | Функция заполнителя |
ST_IsSimple() | Проста ли геометрия |
ST_IsValid() | Допустима ли геометрия |
ST_LatFromGeoHash() | Возвратит широту из значения geohash
|
ST_Length()
| Возвратит длину LineString |
ST_LineFromText() , ST_LineStringFromText() |
Собирает LineString из WKT |
ST_LineFromWKB() , ST_LineStringFromWKB() |
Собирает LineString из WKB |
ST_LongFromGeoHash() | Возвратит долготу из значения geohash
|
ST_MakeEnvelope() | Прямоугольник вокруг двух точек |
ST_MLineFromText() , ST_MultiLineStringFromText() |
Собирает MultiLineString из WKT |
ST_MLineFromWKB() , ST_MultiLineStringFromWKB() |
Собирает MultiLineString из WKB |
ST_MPointFromText() , ST_MultiPointFromText() |
Собирает MultiPoint из WKT |
ST_MPointFromWKB() , ST_MultiPointFromWKB() |
Собирает MultiPoint из WKB |
ST_MPolyFromText() , ST_MultiPolygonFromText() |
Собирает MultiPolygon из WKT |
ST_MPolyFromWKB() , ST_MultiPolygonFromWKB() |
Собирает MultiPolygon из WKB |
ST_NumGeometries() | Число конфигураций в наборе геометрии
|
ST_NumInteriorRing() , ST_NumInteriorRings() |
Число углов в Polygon |
ST_NumPoints() | Число точек в LineString |
ST_Overlaps() | Перекрывает ли одна геометрия другую |
ST_PointFromGeoHash() |
Конвертирует geohash в POINT |
ST_PointFromText() | Собирает Point из WKT |
ST_PointFromWKB() | Собирает Point из WKB |
ST_PointN()
| Возвратит N-ую точку LineString |
ST_PolyFromText() , ST_PolygonFromText() |
Собирает Polygon из WKT |
ST_PolyFromWKB() , ST_PolygonFromWKB() |
Собирает Polygon из WKB |
ST_Simplify() | Возвратит упрощенную геометрию |
ST_SRID()
| Возвратит пространственный ссылочный системный
ID для геометрии |
ST_StartPoint() | Стартовая Point LineString |
ST_SymDifference() | Возвратит набор точек
симметрического различия двух конфигураций |
ST_Touches() | Касается ли одна геометрия другой |
ST_Union()
| Возвратит набор общих точек двух конфигураций |
ST_Validate() | Возвратит утвержденную геометрию |
ST_Within()
| Является ли одна геометрия в пределах другой |
ST_X()
| Координата X Point |
ST_Y()
| Координата Y Point |
13.15.2.
Обработка параметров пространственными функциями
Пространственные значения, или конфигурации, имеют свойства, описанные в
разделе 12.5.2.2.
Следующее обсуждение рассматривает общие пространственные функциональные
характеристики параметров. У определенных функций или групп функций могут
быть дополнительные характеристики, как обсуждается в разделах, где
те функции описаны.
Пространственные функции определены только для допустимых значений
геометрии. Если недопустимую геометрию передают к пространственной
функции, результат неопределен.
Spatial Reference Identifier (SRID) идентифицирует координатное
пространство, в котором определена геометрия. В MySQL значение SRID целое
число, связанное со значением геометрии. Однако, все вычисления сделаны,
принимая SRID 0, представляя декартовские (плоские) координаты, независимо от
фактического значения SRID. В будущем вычисления могут использовать указанные
значения SRID. Чтобы гарантировать поведение для SRID 0, создавайте
конфигурации, используя SRID 0. SRID 0 является значением по умолчанию для
новых конфигураций, если никакой SRID не определен.
Максимальное применимое значение SRID 232-1.
Если большее значение дано, используются только первые 32 бита.
Значения геометрии, произведенные любой пространственной функцией,
наследуют SRID параметров геометрии.
Пространственные функции, которые берут много параметров геометрии,
требуют, чтобы у тех параметров было то же самое значение SRID. Предполагая,
что SRIDs равны, пространственные функции ничего не делают с ними после
выполнения проверки равенства, значения геометрии неявно обработаны,
используя декартовские координаты. Если пространственная функция возвращает
ER_GIS_DIFFERENT_SRIDS
, это означает, что у параметров геометрии не было того же самого
SRID. Вы должны изменить их, чтобы иметь тот же самый SRID.
Пространственные функции возвращают ошибку
ER_GIS_INVALID_DATA
, если передан недопустимый параметр геометрии.
Open Geospatial Consortium требует, чтобы вводные многоугольники
уже были закрытыми, таким образом, открытые многоугольники отклонены как
недопустимые вместо того, чтобы закрыть.
Пустая обработка набора геометрии следующяя:
пустой входной набор геометрии WKT может быть определен как
'GEOMETRYCOLLECTION()' . Это также вывод WKT, следующий из
пространственной работы, которая производит пустой набор геометрии.
Во время парсинга вложенного набора геометрии набор обработан, и его
основные компоненты используются в различных операциях GIS, чтобы вычислить
результаты. Это предоставляет дополнительную гибкость пользователям, потому
что не нужно касаться уникальности данных о геометрии. Вложенные наборы
геометрии могут быть произведены из вложенных вызовов функции GIS.
13.15.3.
Функции, которые создают значения геометрии из значений WKT
Эти функции берут в качестве параметров представление Well-Known Text
(WKT) и, произвольно, SRID. Они возвращают соответствующую геометрию.
ST_GeomFromText()
принимает значение WKT любого типа геометрии как первый параметр.
Другие функции обеспечивают определенные для типа функции конструкции для
значений геометрии каждого типа геометрии.
Функции, которые принимают параметры набора геометрии WKT, понимают оба
синтаксиса: стандартный OpenGIS 'GEOMETRYCOLLECTION EMPTY' и
нестандартный MySQL 'GEOMETRYCOLLECTION()' . Функции, которые
производят значения WKT, производят стандартный
синтаксис 'GEOMETRYCOLLECTION EMPTY' :
mysql> SET @s1 = ST_GeomFromText('GEOMETRYCOLLECTION()');
mysql> SET @s2 = ST_GeomFromText('GEOMETRYCOLLECTION EMPTY');
mysql> SELECT ST_AsWKT(@s1), ST_AsWKT(@s2);
+--------------------------+--------------------------+
| ST_AsWKT(@s1) | ST_AsWKT(@s2) |
+--------------------------+--------------------------+
| GEOMETRYCOLLECTION EMPTY | GEOMETRYCOLLECTION EMPTY |
+--------------------------+--------------------------+
Для описания формата WKT см. раздел
12.5.3.1.1.
ST_GeomCollFromText(
wkt [,srid ]) ,
ST_GeometryCollectionFromText(wkt [,srid
]) ,
ST_GeomCollFromTxt(
wkt [,srid ])
Конструирует значение GeometryCollection ,
используя его представление WKT и SRID.
mysql> SET @g = "MULTILINESTRING((10 10, 11 11), (9 9, 10 10))";
mysql> SELECT ST_AsText(ST_GeomCollFromText(@g));
+--------------------------------------------+
| ST_AsText(ST_GeomCollFromText(@g)) |
+--------------------------------------------+
| MULTILINESTRING((10 10,11 11),(9 9,10 10)) |
+--------------------------------------------+
ST_GeomFromText(
wkt [,srid ]) ,
ST_GeometryFromText(
wkt [,srid ])
Конструирует значение геометрии любого типа, используя его
представление WKT и SRID.
ST_LineFromText(
wkt [,srid ]) ,
ST_LineStringFromText(
wkt [,srid ])
Конструирует значение LineString , используя его
представление WKT и SRID.
ST_MLineFromText(
wkt [,srid ]) ,
ST_MultiLineStringFromText(wkt [,srid
])
Конструирует MultiLineString
используя его представление WKT и SRID.
ST_MPointFromText(
wkt [,srid ]) ,
ST_MultiPointFromText(
wkt [,srid ])
Конструирует MultiPoint
используя его представление WKT и SRID.
В MySQL 8.0 пространственные функции вроде
ST_MPointFromText()
и
ST_GeomFromText() , которые принимают представления WKT-формата
MultiPoint разрешают отдельным пунктам в пределах значений быть
окруженными круглыми скобками. Например, оба из следующих
вызовов функции допустимы:
ST_MPointFromText('MULTIPOINT (1 1, 2 2, 3 3)')
ST_MPointFromText('MULTIPOINT ((1 1), (2 2), (3 3))')
ST_MPolyFromText(
wkt [,srid ]) ,
ST_MultiPolygonFromText(
wkt [,srid ])
Конструирует MultiPolygon
используя его представление WKT и SRID.
ST_PointFromText(
wkt [,srid ])
Конструирует Point используя его представление WKT и SRID.
ST_PolyFromText(
wkt [,srid ]) ,
ST_PolygonFromText(
wkt [,srid ])
Конструирует Polygon используя его представление WKT и SRID.
13.15.4. Функции, которые создают
значения геометрии из значений WKB
Эти функции берут в качестве параметров
BLOB , содержащий представление
Well-Known Binary (WKB) и, произвольно, пространственный ссылочный системный
идентификатор (SRID). Они возвращают соответствующую геометрию.
Эти функции также принимают объекты геометрии для совместимости с
возвращаемым значением функций в
разделе 13.15.5.
Таким образом, те функции могут использоваться, чтобы обеспечить первый
параметр функциям в этом разделе.
ST_GeomFromWKB()
принимает значение WKB любого типа геометрии как
первый параметр. Другие функции обеспечивают определенные для типа функции
для конструкции значений геометрии каждого типа.
ST_GeomCollFromWKB(
wkb [,srid ]) ,
ST_GeometryCollectionFromWKB(wkb [,
srid ])
Конструирует GeometryCollection
используя его представление WKB и SRID.
ST_GeomFromWKB(
wkb [,srid ]) ,
ST_GeometryFromWKB(
wkb [,srid ])
Конструирует значение геометрии любого типа, используя его
представление WKB и SRID.
ST_LineFromWKB(
wkb [,srid ]) ,
ST_LineStringFromWKB(
wkb [,srid ])
Конструирует LineString , используя его
представление WKB и SRID.
ST_MLineFromWKB(
wkb [,srid ]) ,
ST_MultiLineStringFromWKB(wkb [,
srid ])
Конструирует MultiLineString , используя его
представление WKB и SRID.
ST_MPointFromWKB(
wkb [,srid ]) ,
ST_MultiPointFromWKB(
wkb [,srid ])
Конструирует MultiPoint , используя его
представление WKB и SRID.
ST_MPolyFromWKB(
wkb [,srid ]) ,
ST_MultiPolygonFromWKB(
wkb [,srid ])
Конструирует MultiPolygon , используя его
представление WKB и SRID.
ST_PointFromWKB(
wkb [,srid ])
Конструирует Point , используя его
представление WKB и SRID.
ST_PolyFromWKB(
wkb [,srid ]) ,
ST_PolygonFromWKB(
wkb [,srid ])
Конструирует Polygon , используя его
представление WKB и SRID.
13.15.5.
Функции MySQL, которые создают значения геометрии
MySQL обеспечивает ряд полезных нестандартных функций для того, чтобы
создать значения геометрии. Функции, описанные в этом разделе, являются
расширениями MySQL к спецификации OpenGIS.
Эти функции производят объекты геометрии или из значений WKB или из
объектов геометрии как параметры. Если какой-либо параметр не надлежащий WKB
или представление геометрии надлежащего типа объекта,
возвращаемое значение NULL .
Например, Вы можете вставить возвращаемое значение геометрии из
Point()
непосредственно в столбец POINT :
INSERT INTO t1 (pt_col) VALUES(Point(1,2));
GeometryCollection(
g1 ,g2 ,...)
Конструирует GeometryCollection .
GeometryCollection()
возвращает все надлежащие конфигурации в параметре, даже если
присутствует неподдержанная геометрия.
GeometryCollection()
без параметров разрешена как способ создать пустую геометрию.
LineString(pt1
,pt2 ,...)
Конструирует LineString значение из многих параметров
Point или WKB Point . Если число параметров меньше,
чем два, возвращаемое значение NULL .
MultiLineString(
ls1 ,ls2 ,...)
Конструирует MultiLineString с использованием значения
LineString или WKB LineString .
MultiPoint(pt1
, pt2 ,...)
Конструирует MultiPoint с использованием значения
Point или WKB Point .
MultiPolygon(
poly1 ,poly2 ,...)
Конструирует MultiPolygon из ряда параметров
Polygon или WKB Polygon .
Point(x ,
y )
Конструирует Point с использованием его координат.
Polygon(ls1 ,
ls2 ,...)
Конструирует Polygon значение из многих параметров
LineString или WKB LineString .
Если какой-либо параметр не представляет LinearRing
(то есть, не закрытый и простое LineString ),
возвращаемое значение NULL .
13.15.6.
Конверсионные функции формата геометрии
MySQL поддерживает функции, перечисленные в этом разделе для того, чтобы
преобразовать значения геометрии из внутреннего формата геометрии в формат
WKB или WKT.
Кроме того, есть функции, чтобы преобразовать строку из WKT или WKB
к внутреннему формату геометрии. См. разделы
13.15.3 и
13.15.4.
Функции, которые принимают параметры набора геометрии WKT, понимают оба
синтаксиса: OpenGIS 'GEOMETRYCOLLECTION EMPTY' и MySQL
'GEOMETRYCOLLECTION()' . Функции, которые производят значения
WKT, производят стандартный синтаксис 'GEOMETRYCOLLECTION EMPTY' :
mysql> SET @s1 = ST_GeomFromText('GEOMETRYCOLLECTION()');
mysql> SET @s2 = ST_GeomFromText('GEOMETRYCOLLECTION EMPTY');
mysql> SELECT ST_AsWKT(@s1), ST_AsWKT(@s2);
+--------------------------+--------------------------+
| ST_AsWKT(@s1) | ST_AsWKT(@s2) |
+--------------------------+--------------------------+
| GEOMETRYCOLLECTION EMPTY | GEOMETRYCOLLECTION EMPTY |
+--------------------------+--------------------------+
ST_AsBinary(g
) ,
ST_AsWKB(g
)
Преобразовывает значение во внутреннем формате геометрии к его
представлению WKB и возвращает двоичный результат.
SELECT ST_AsBinary(g) FROM geom;
ST_AsText(g
) ,
ST_AsWKT(g
)
Преобразовывает значение во внутреннем формате геометрии к его
представлению WKT и возвращает строковый результат.
mysql> SET @g = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_AsText(ST_GeomFromText(@g));
+--------------------------------+
| ST_AsText(ST_GeomFromText(@g)) |
+--------------------------------+
| LINESTRING(1 1,2 2,3 3) |
+--------------------------------+
Вывод для значения MultiPoint
включает круглые скобки вокруг каждого пункта. Например:
mysql> SELECT ST_AsText(ST_GeomFromText(@mp));
+---------------------------------+
| ST_AsText(ST_GeomFromText(@mp)) |
+---------------------------------+
| MULTIPOINT((1 1),(2 2),(3 3)) |
+---------------------------------+
13.15.7.
Функции свойства геометрии
Каждая функция, которая принадлежит этой группе, берет значение геометрии
в качестве своего параметра и возвращает некоторое количественное или
качественное свойство геометрии. Некоторые функции ограничивают свой тип
параметра. Такие функции возвращают NULL , если параметр имеет
неправильный тип геометрии. Например,
ST_Area()
вернет NULL , если тип объекта не
Polygon или MultiPolygon .
13.15.7.1.
Общие функции свойства геометрии
Функции, перечисленные в этом разделе, не ограничивают свой параметр
и принимают значение геометрии любого типа.
ST_Dimension(g
)
Возвращает врожденное измерение значения геометрии
g или NULL , если параметр
NULL . Измерение может быть -1, 0, 1 или 2. Смысл этих значений
дан в разделе 12.5.2.2.
mysql> SELECT ST_Dimension(ST_GeomFromText('LineString(1 1,2 2)'));
+------------------------------------------------------+
| ST_Dimension(ST_GeomFromText('LineString(1 1,2 2)')) |
+------------------------------------------------------+
| 1 |
+------------------------------------------------------+
ST_Envelope(g
)
Возвращает минимальный ограничительный прямоугольник (MBR) для значения
геометрии g или NULL , если параметр
NULL . Результат возвращен как значение Polygon ,
которое определено угловыми точками ограничивающего прямоугольника:
POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
mysql> SELECT ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,2 2)')));
+----------------------------------------------------------------+
| ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,2 2)'))) |
+----------------------------------------------------------------+
| POLYGON((1 1, 2 1, 2 2, 1 2, 1 1)) |
+----------------------------------------------------------------+
Если параметр точка или вертикальный (или горизонтальный) линейный
сегмент, ST_Envelope()
возвращает точку или линейный сегмент как его MBR вместо того, чтобы
возвратить недопустимый многоугольник:
mysql> SELECT ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,1 2)')));
+----------------------------------------------------------------+
| ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,1 2)'))) |
+----------------------------------------------------------------+
| LINESTRING(1 1, 1 2) |
+----------------------------------------------------------------+
ST_GeometryType(
g )
Возвращает двоичную строку, указывающую на название типа геометрии,
к которой принадлежит g или NULL , если
параметр NULL . Имя соответствует одному
из подклассов Geometry .
mysql> SELECT ST_GeometryType(ST_GeomFromText('POINT(1 1)'));
+------------------------------------------------+
| ST_GeometryType(ST_GeomFromText('POINT(1 1)')) |
+------------------------------------------------+
| POINT |
+------------------------------------------------+
ST_IsEmpty(g
)
Эта функция заполнитель, который возвращает 0 для любого допустимого
значения геометрии, 1 для любого недопустимого значения геометрии или
NULL , если параметр NULL .
MySQL не поддерживает значения GIS EMPTY , такие
как POINT EMPTY .
ST_IsSimple(g
)
Возвращает 1, если значение геометрии g
не имеет никаких аномальных геометрических пунктов, таких как
самопересечение или самокасание.
ST_IsSimple()
возвращает 0, если параметр не прост и NULL ,
если параметр NULL .
Описание каждого геометрического класса, данного ранее в главе, включает
особые условия, которые заставляют случай того класса быть классифицированным
как не простой. См. раздел
12.5.2.1.
ST_SRID(g [,
new_srid_val ])
В MySQL значение SRID только целое число, связанное со значением
геометрии. Все вычисления сделаны, принимая Евклидову (плоскую) геометрию.
С единственным параметром, представляющим допустимый объект геометрии
g , ST_SRID()
возвращает целое число, указывающее на Spatial Reference System
ID для g или NULL , если параметр
NULL .
Если параметр не синтаксически правильно построенная геометрия, происходит
ошибка
ER_GIS_INVALID_DATA .
Если дополнительный второй параметр, представляющий допустимое значение
SRID дан, ST_SRID()
возвращает объект с тем же самым типом, как его первый параметр, имеющий
значение SRID, равное второму параметру, или NULL , если любой
параметр NULL . Эти условия применяются:
Обработка ошибок для первого параметра, что касается синтаксиса
единственного параметра, сделана, как описано ранее.
- Если значение SRID во втором параметре не в пределах диапазона
32-битного целого числа без знака, происходит ошибка
ER_DATA_OUT_OF_RANGE
.
- Если значение SRID во втором параметре не обращается к
пространственной ссылочной системе, происходит ошибка
ER_SRS_NOT_FOUND
.
mysql> SET @g = ST_GeomFromText('LineString(1 1,2 2)', 0);
mysql> SELECT ST_SRID(@g);
+-------------+
| ST_SRID(@g) |
+-------------+
| 0 |
+-------------+
mysql> SET @g2 = ST_SRID(@g, 4326);
mysql> SELECT ST_SRID(@g2);
+--------------+
| ST_SRID(@g2) |
+--------------+
| 4326 |
+--------------+
13.15.7.2.
Функции и свойства точки
Point состоит из координат X и Y, которые могут быть
получены, используя функции ST_X()
и ST_Y() ,
соответственно. Эти функции также разрешают дополнительный второй параметр,
который определяет X или значение координаты Y, когда функциональный
результат Point является объектом от первого параметра с
соответствующей измененной координатой, чтобы быть равным второму параметру.
ST_X(p [,
new_x_val ])
С единственным параметром, представляющим допустимый объект
Point object p
ST_X()
возвращает значение X-координаты p как число двойной
точности или NULL , если параметр NULL .
Эти условия применяются:
Если дополнительный второй параметр, представляющий допустимое значение
X-координаты, дан, ST_X()
возвращает объект Point с X-координатой, равной второму
параметру, или NULL , если любой параметр NULL .
Эти условия применяются:
Обработка ошибок для первого параметра, что касается синтаксиса
единственного параметра, сдалана, как описано ранее.
- Если координатное значение во втором параметре
-inf , +inf или NaN , происходит ошибка
ER_DATA_OUT_OF_RANGE
.
mysql> SELECT ST_X(POINT(56.7, 53.34));
+--------------------------+
| ST_X(POINT(56.7, 53.34)) |
+--------------------------+
| 56.7 |
+--------------------------+
mysql> SELECT ST_AsText(ST_X(POINT(56.7, 53.34), 10.5));
+-------------------------------------------+
| ST_AsText(ST_X(POINT(56.7, 53.34), 10.5)) |
+-------------------------------------------+
| POINT(10.5 53.34) |
+-------------------------------------------+
ST_Y(p [,
new_y_val ])
С единственным параметром, представляющим допустимый объект
Point p ,
ST_Y()
возвращает значение Y-координаты p как число
двойной точности или NULL , если параметр NULL .
Эти условия применяются:
Если дополнительный второй параметр, представляющий допустимое значение
Y-координаты, дан, ST_Y()
возвращает объект Point с Y-координатой, равной второму
параметру, или NULL , если любой параметр NULL .
Эти условия применяются:
mysql> SELECT ST_Y(POINT(56.7, 53.34));
+--------------------------+
| ST_Y(POINT(56.7, 53.34)) |
+--------------------------+
| 53.34 |
+--------------------------+
mysql> SELECT ST_AsText(ST_Y(POINT(56.7, 53.34), 10.5));
+-------------------------------------------+
| ST_AsText(ST_Y(POINT(56.7, 53.34), 10.5)) |
+-------------------------------------------+
| POINT(56.7 10.5) |
+-------------------------------------------+
13.15.7.3.
Функции и свойства LineString и MultiLineString
LineString состоит из значений Point .
Вы можете извлечь особые точки LineString ,
посчитайте число точек, которое это содержит, или получить его длину.
Некоторые функции в этом разделе также работают на значениях
MultiLineString .
ST_EndPoint(ls
)
Возвращает Point , конечную точку значения
LineString ls .
mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_AsText(ST_EndPoint(ST_GeomFromText(@ls)));
+----------------------------------------------+
| ST_AsText(ST_EndPoint(ST_GeomFromText(@ls))) |
+----------------------------------------------+
| POINT(3 3) |
+----------------------------------------------+
ST_IsClosed(ls
)
Для значения LineString ls
ST_IsClosed()
возвращает 1, если ls закрыт (то есть, значения
ST_StartPoint() и
ST_EndPoint()
то же самое).
Для значения MultiLineString ls
ST_IsClosed()
возвращает 1, если ls закрыт (то есть, значения
ST_StartPoint() и
ST_EndPoint() те же
самые для каждой LineString в ls ).
ST_IsClosed()
возвращает 0, если ls не закрыт, и
NULL , если ls NULL .
mysql> SET @ls1 = 'LineString(1 1,2 2,3 3,2 2)';
mysql> SET @ls2 = 'LineString(1 1,2 2,3 3,1 1)';
mysql> SELECT ST_IsClosed(ST_GeomFromText(@ls1));
+------------------------------------+
| ST_IsClosed(ST_GeomFromText(@ls1)) |
+------------------------------------+
| 0 |
+------------------------------------+
mysql> SELECT ST_IsClosed(ST_GeomFromText(@ls2));
+------------------------------------+
| ST_IsClosed(ST_GeomFromText(@ls2)) |
+------------------------------------+
| 1 |
+------------------------------------+
mysql> SET @ls3 = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
mysql> SELECT ST_IsClosed(ST_GeomFromText(@ls3));
+------------------------------------+
| ST_IsClosed(ST_GeomFromText(@ls3)) |
+------------------------------------+
| 0 |
+------------------------------------+
ST_Length(ls
)
Возвращает число двойной точности, указывающее на длину
значения LineString или MultiLineString
ls в его связанной пространственной ссылке. Длина
MultiLineString равна сумме длин элементов.
mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_Length(ST_GeomFromText(@ls));
+---------------------------------+
| ST_Length(ST_GeomFromText(@ls)) |
+---------------------------------+
| 2.8284271247461903 |
+---------------------------------+
mysql> SET @mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
mysql> SELECT ST_Length(ST_GeomFromText(@mls));
+----------------------------------+
| ST_Length(ST_GeomFromText(@mls)) |
+----------------------------------+
| 4.242640687119286 |
+----------------------------------+
ST_NumPoints(ls
)
Возвращает число объектов Point в значении
LineString ls .
mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_NumPoints(ST_GeomFromText(@ls));
+------------------------------------+
| ST_NumPoints(ST_GeomFromText(@ls)) |
+------------------------------------+
| 3 |
+------------------------------------+
ST_PointN(ls
,N )
Возвращает N -ый Point в
Linestring ls .
Точки пронумерованы, начиная с 1.
mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_AsText(ST_PointN(ST_GeomFromText(@ls),2));
+----------------------------------------------+
| ST_AsText(ST_PointN(ST_GeomFromText(@ls),2)) |
+----------------------------------------------+
| POINT(2 2) |
+----------------------------------------------+
ST_StartPoint(
ls )
Возвращает Point , который является стартовой точкой
LineString ls .
mysql> SET @ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT ST_AsText(ST_StartPoint(ST_GeomFromText(@ls)));
+------------------------------------------------+
| ST_AsText(ST_StartPoint(ST_GeomFromText(@ls))) |
+------------------------------------------------+
| POINT(1 1) |
+------------------------------------------------+
13.15.7.4.
Функции и свойства Polygon и MultiPolygon
Эти функции возвращают свойства значения Polygon
или MultiPolygon .
ST_Area(poly
)
Возвращает число двойной точности, указывающее на область параметра, как
измерено в его пространственной ссылочной системе.
Для параметров измерения 0 или 1 результат 0.
Результат сумма значений областей всех компонентов для набора геометрии.
Если набор геометрии пуст, его область возвращена как 0.
mysql> SET @poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';
mysql> SELECT ST_Area(ST_GeomFromText(@poly));
+---------------------------------+
| ST_Area(ST_GeomFromText(@poly)) |
+---------------------------------+
| 4 |
+---------------------------------+
mysql> SET @mpoly =
-> 'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))';
mysql> SELECT ST_Area(ST_GeomFromText(@mpoly));
+----------------------------------+
| ST_Area(ST_GeomFromText(@mpoly)) |
+----------------------------------+
| 8 |
+----------------------------------+
ST_Centroid(mpoly
)
Возвращает математическую среднюю точку для
MultiPolygon mpoly как Point .
Эта функция обрабатывает наборы геометрии, вычисляя центроидный пункт для
компонентов самого высокого измерения в наборе. Такие компоненты извлечены и
превращены в MultiPolygon , MultiLineString или
MultiPoint для центроидного вычисления. Если параметр пустой
набор геометрии, возвращаемое значение NULL .
mysql> SET @poly = ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),
-> (5 5,7 5,7 7,5 7,5 5))');
mysql> SELECT ST_GeometryType(@poly),ST_AsText(ST_Centroid(@poly));
+------------------------+--------------------------------------------+
| ST_GeometryType(@poly) | ST_AsText(ST_Centroid(@poly)) |
+------------------------+--------------------------------------------+
| POLYGON | POINT(4.958333333333333 4.958333333333333) |
+------------------------+--------------------------------------------+
ST_ExteriorRing(
poly )
Возвращает внешнее кольцо Polygon
poly как LineString .
mysql> SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),
-> (1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly)));
+----------------------------------------------------+
| ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly))) |
+----------------------------------------------------+
| LINESTRING(0 0,0 3,3 3,3 0,0 0) |
+----------------------------------------------------+
ST_InteriorRingN(
poly ,N )
Возвращает N -ое кольцо для Polygon
poly как LineString .
Кольца пронумерованы, начиная с 1.
mysql> SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),
-> (1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1));
+-------------------------------------------------------+
| ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1)) |
+-------------------------------------------------------+
| LINESTRING(1 1,1 2,2 2,2 1,1 1) |
+-------------------------------------------------------+
ST_NumInteriorRing(
poly ) ,
ST_NumInteriorRings(
poly )
Возвращается число колец для Polygon
poly .
mysql> SET @poly =
-> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT ST_NumInteriorRings(ST_GeomFromText(@poly));
+---------------------------------------------+
| ST_NumInteriorRings(ST_GeomFromText(@poly)) |
+---------------------------------------------+
| 1 |
+---------------------------------------------+
13.15.7.5.
Функции и свойства GeometryCollection
Эти функции возвращают свойства значения GeometryCollection .
ST_GeometryN(gc
,N )
Возвращает N -ую геометрию в
GeometryCollection gc .
Геометрии нумерованы, начиная с 1.
mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql> SELECT ST_AsText(ST_GeometryN(ST_GeomFromText(@gc),1));
+-------------------------------------------------+
| ST_AsText(ST_GeometryN(ST_GeomFromText(@gc),1)) |
+-------------------------------------------------+
| POINT(1 1) |
+-------------------------------------------------+
ST_NumGeometries(
gc )
Возвращает число конфигураций в GeometryCollection
gc .
mysql> SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql> SELECT ST_NumGeometries(ST_GeomFromText(@gc));
+----------------------------------------+
| ST_NumGeometries(ST_GeomFromText(@gc)) |
+----------------------------------------+
| 2 |
+----------------------------------------+
13.15.8.
Пространственные функции и операторы
OpenGIS предлагает много функций, которые могут произвести конфигурации.
Они разработаны, чтобы осуществить пространственные операторы.
Эти функции поддерживают все комбинации типа параметра кроме тех, которые
являются неподходящими согласно спецификации Open Geospatial Consortium.
ST_Buffer(g
,d [,strategy1 [,
strategy2 [,strategy3 ]]])
Возвращает геометрию, которая представляет все пункты, расстояние которых
от геометрии g меньше или равно
d , или NULL , если какой-либо параметр
NULL . SRID параметра геометрии должен быть 0, потому что
ST_Buffer()
поддерживает только декартову систему координат. Для недопустимого параметра
геометрии будет ошибка
ER_GIS_INVALID_DATA
.
Если параметр геометрии пуст,
ST_Buffer()
возвращает пустую геометрию.
Если расстояние 0,
ST_Buffer()
возвращает неизменный параметр геометрии:
mysql> SET @pt = ST_GeomFromText('POINT(0 0)');
mysql> SELECT ST_AsText(ST_Buffer(@pt, 0));
+------------------------------+
| ST_AsText(ST_Buffer(@pt, 0)) |
+------------------------------+
| POINT(0 0) |
+------------------------------+
ST_Buffer()
поддерживает отрицательные расстояния для Polygon и
MultiPolygon и для наборов геометрии, содержащих значения
Polygon или MultiPolygon .
Результат может быть пустой геометрией. Ошибка
ER_WRONG_ARGUMENTS
происходит для ST_Buffer()
с отрицательным расстоянием для Point ,
MultiPoint , LineString и
MultiLineString и для наборов геометрии, не содержащих любого
значения Polygon или MultiPolygon .
ST_Buffer()
разрешает до трех дополнительных параметров стратегии после параметра
расстояния. Стратегии влияют на буферное вычисление. Эти параметры строковые
значения байта, произведенные
ST_Buffer_Strategy()
, чтобы использовать для стратегий точки, соединения и завершения:
До одной стратегии каждого типа может быть определено, и их можно задать
в любом порядке. Если много стратегий данного типа определено, происходит
ошибка ER_WRONG_ARGUMENTS
.
mysql> SET @pt = ST_GeomFromText('POINT(0 0)');
mysql> SET @pt_strategy = ST_Buffer_Strategy('point_square');
mysql> SELECT ST_AsText(ST_Buffer(@pt, 2, @pt_strategy));
+--------------------------------------------+
| ST_AsText(ST_Buffer(@pt, 2, @pt_strategy)) |
+--------------------------------------------+
| POLYGON((-2 -2,2 -2,2 2,-2 2,-2 -2)) |
+--------------------------------------------+
mysql> SET @ls = ST_GeomFromText('LINESTRING(0 0,0 5,5 5)');
mysql> SET @end_strategy = ST_Buffer_Strategy('end_flat');
mysql> SET @join_strategy = ST_Buffer_Strategy('join_round', 10);
mysql> SELECT ST_AsText(ST_Buffer(@ls, 5, @end_strategy, @join_strategy))
+---------------------------------------------------------------+
| ST_AsText(ST_Buffer(@ls, 5, @end_strategy, @join_strategy)) |
+---------------------------------------------------------------+
| POLYGON((5 5,5 10,0 10,-3.5355339059327373 8.535533905932738, |
| -5 5,-5 0,0 0,5 0,5 5)) |
+---------------------------------------------------------------+
ST_Buffer_Strategy(
strategy [,points_per_circle ])
Эта функция возвращает строку байтов стратегии для использования с
ST_Buffer() , чтобы
влиять на буферное вычисление. Результат NULL , если какой-либо
параметр NULL . Если какой-либо параметр недопустим, происходит
ошибка
ER_WRONG_ARGUMENTS .
Информация о стратегиях доступна на
Boost.org.
Первый параметр должен быть строкой, указывающей на опцию стратегии:
Если первый параметр 'point_circle' ,
'join_round' , 'join_miter' или
'end_round' , параметр points_per_circle
должен быть дан как положительное числовое значение. Максимум
points_per_circle значение системной переменной
max_points_in_geometry . Если первый параметр
'point_square' или 'end_flat' , параметр
points_per_circle не должен быть дан или происходит
ошибка ER_WRONG_ARGUMENTS
.
Для примеров см. описание
ST_Buffer() .
ST_ConvexHull(g
)
Возвращает геометрию, которая представляет выпуклый
контур значения геометрии g .
Эта функция вычисляет выпуклый контур геометрии первой проверкой, являются
ли ее точки колинеарными вершинами. Функция возвращает линейный контур если
это так, иначе контур многоугольника. Эта функция обрабатывает наборы
геометрии, извлекая все точки вершин всех компонентов набора, создавая
значение MultiPoint из них, и вычисляя его выпуклый контур. Если
параметр пустой набор геометрии, возвращаемое значение NULL .
mysql> SET @g = 'MULTIPOINT(5 0,25 0,15 10,15 25)';
mysql> SELECT ST_AsText(ST_ConvexHull(ST_GeomFromText(@g)));
+-----------------------------------------------+
| ST_AsText(ST_ConvexHull(ST_GeomFromText(@g))) |
+-----------------------------------------------+
| POLYGON((5 0,25 0,15 25,5 0)) |
+-----------------------------------------------+
ST_Difference(g1
, g2 )
Возвращает геометрию, которая представляет различие в наборе точек
значений геометрий g1 и g2 .
mysql> SET @g1 = POINT(1,1), @g2 = POINT(2,2);
mysql> SELECT ST_AsText(ST_Difference(@g1, @g2));
+------------------------------------+
| ST_AsText(ST_Difference(@g1, @g2)) |
+------------------------------------+
| POINT(1 1) |
+------------------------------------+
ST_Intersection(
g1 , g2 )
Возвращает геометрию, которая представляет пересечение набора точек
значений геометрий g1 и g2 .
mysql> SET @g1 = ST_GeomFromText('LineString(1 1, 3 3)');
mysql> SET @g2 = ST_GeomFromText('LineString(1 3, 3 1)');
mysql> SELECT ST_AsText(ST_Intersection(@g1, @g2));
+--------------------------------------+
| ST_AsText(ST_Intersection(@g1, @g2)) |
+--------------------------------------+
| POINT(2 2) |
+--------------------------------------+
ST_SymDifference(
g1 , g2 )
Возвращает геометрию, которая представляет симметрическое различие
набора точек значений геометрий g1 и
g2 , которая определена как:
g1 symdifference g2 := (g1 union g2 )
difference (g1 intersection g2 )
Или в нотации вызова функции:
ST_SymDifference(g1 , g2 ) =
ST_Difference(ST_Union(g1 ,
g2 ),
ST_Intersection(g1 ,
g2 ))
mysql> SET @g1 = POINT(1,1), @g2 = POINT(2,2);
mysql> SELECT ST_AsText(ST_SymDifference(@g1, @g2));
+-------------------------------------------+
| ST_AsText(ST_SymDifference(@g1, @g2)) |
+-------------------------------------------+
| GEOMETRYCOLLECTION(POINT(1 1),POINT(2 2)) |
+-------------------------------------------+
ST_Union(g1 ,
g2 )
Возвращает геометрию, которая представляет союз наборов точек
значений геометрий g1 и g2 .
mysql> SET @g1 = ST_GeomFromText('LineString(1 1, 3 3)');
mysql> SET @g2 = ST_GeomFromText('LineString(1 3, 3 1)');
mysql> SELECT ST_AsText(ST_Union(@g1, @g2));
+--------------------------------------+
| ST_AsText(ST_Union(@g1, @g2)) |
+--------------------------------------+
| MULTILINESTRING((1 1,3 3),(1 3,3 1)) |
+--------------------------------------+
Кроме того, раздел 13.15.7
обсуждает несколько функций, которые создают новые
конфигурации из существующих.
13.15.9.
Функции, которые проверяют пространственные отношения
между объектами геометрии
Функции, описанные в этом разделе, берут две конфигурации в качестве
параметров и возвращают качественное или количественное отношение между ними.
MySQL осуществляет два набора функций, используя имена функций,
определенные спецификацией OpenGIS. Один набор проверяет отношения между
двумя значениями геометрии, используя точные формы объекта, другой
использует минимальный ограничительный прямоугольник объекта.
Есть также MySQL-специфичный набор функций, доступных, чтобы проверить
отношения между двумя значениями геометрии.
13.15.9.1.
Пространственные функции с использованием формы объекта
Спецификация OpenGIS определяет следующие функции. Они проверяют отношения
между двумя значениями геометрии g1 и g2 , с
использованием точных форм объекта. Возвращаемые значения 1 и 0 указывают на
истину и ложь, соответственно, за исключением
ST_Distance() ,
который возвращает значения расстояния.
Эти функции поддерживают все комбинации типа параметра кроме тех, которые
являются неподходящими согласно Open Geospatial Consortium. Они возвращают
ложнь, если вызваны с неподходящей комбинацией типов параметров геометрии.
Например, ST_Overlaps()
возвращает ложь, если вызвана с конфигурациями различных измерений.
ST_Contains(g1
,g2 )
Возвращает 1 или 0, чтобы указать, содержит ли
g1 полностью g2 .
Это проверяет противоположные отношения как
ST_Within() .
ST_Crosses(g1
,g2 )
Возвращает 1, если g1 пространственно пересекает
g2 . Возвращает NULL , если g1
Polygon или MultiPolygon , или если
g2 Point или
MultiPoint . Иначе вернет 0.
Эта функция возвращает 0, если вызвана с неподходящей комбинацией типов
параметров геометрии. Например, это возвращает 0, если первый параметр
Polygon или MultiPolygon и\или второй параметр
Point или MultiPoint .
Термин пространственно пересекается обозначает
пространственное отношение между двумя данными конфигурациями, у которых
есть следующие свойства:
ST_Disjoint(g1
,g2 )
Возвращает 1 или 0, чтобы указать, является ли g1
пространственно несвязной (не пересекается) с g2 .
ST_Distance(g1
, g2 )
Возвращает расстояние между g1 и
g2 .
Эта функция обрабатывает наборы геометрии, возвращая самое короткое
расстояние среди всех комбинаций компонентов двух параметров геометрии.
Если любой параметр пустой набор геометрии, возвращаемое значение
NULL .
Если промежуточный или окончательный результат производит NaN или
отрицательное число, эта функция производит ошибку
ER_GIS_INVALID_DATA
.
mysql> SET @g1 = POINT(1,1), @g2 = POINT(2,2);
mysql> SELECT ST_Distance(@g1, @g2);
+-----------------------+
| ST_Distance(@g1, @g2) |
+-----------------------+
| 1.4142135623730951 |
+-----------------------+
ST_Equals(g1
,g2 )
Возвращает 1 или 0, чтобы указать, равно ли пространственно
g1 g2 .
mysql> SET @g1 = POINT(1,1), @g2 = POINT(2,2);
mysql> SELECT ST_Equals(@g1, @g1), ST_Equals(@g1, @g2);
+---------------------+---------------------+
| ST_Equals(@g1, @g1) | ST_Equals(@g1, @g2) |
+---------------------+---------------------+
| 1 | 0 |
+---------------------+---------------------+
ST_Intersects(g1
, g2 )
Возвращает 1 или 0, чтобы указать, пересекается ли пространственно
g1 и g2 .
ST_Overlaps(g1
, g2 )
Возвращает 1 или 0, чтобы указать, перекрывает ли пространственно
g1 g2 . Термин
перекрывает пространственно используется, если
две конфигурации пересекаются и их перекрестные результаты находятся в
геометрии того же самого измерения, но не равны любой из данных конфигураций.
Эта функция возвращает 0, если вызвана с неподходящей комбинацией типов
параметров геометрии. Например, это возвращает 0, если вызвана с
конфигурациями различных измерений, или любой параметр Point .
ST_Touches(g1
,g2 )
Возвращает 1 или 0, чтобы указать, касается ли пространственно
g1 g2 . Две конфигурации
касаются пространственно, если внутренности
конфигураций не пересекаются, но граница одной из конфигураций пересекает
границу или внутренности другой.
Функция возвращает 0, если вызвана с неподходящей комбинацией типов
параметров геометрии. Например, это возвращает 0, если любой из параметров
Point или MultiPoint .
ST_Within(g1
,g2 )
Возвращает 1 или 0, чтобы указать, находится ли
g1 пространственно в пределах g2 .
Это проверяет противоположные отношения как
ST_Contains() .
13.15.9.2.
MySQL-специфичные пространственные функции, использующие
ограничивающие прямоугольники минимума
MySQL обеспечивает несколько функций, которые проверяют отношения между
минимальными ограничительными прямоугольниками двух конфигураций
g1 и g2 . Возвращаемые значения 1 и 0 указывают на
истину и ложь, соответственно.
MBRContains(g1
,g2 )
Возвращает 1 или 0, чтобы указать, содержит ли минимальный ограничительный
прямоугольник g1 такой же прямоугольник
g2 . Это проверяет противоположные отношения как
MBRWithin() .
mysql> SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql> SET @g2 = ST_GeomFromText('Point(1 1)');
mysql> SELECT MBRContains(@g1,@g2), MBRWithin(@g2,@g1);
+----------------------+--------------------+
| MBRContains(@g1,@g2) | MBRWithin(@g2,@g1) |
+----------------------+--------------------+
| 1 | 1 |
+----------------------+--------------------+
MBRCoveredBy(g1
,g2 )
Возвращает 1 или 0, чтобы указать, покрыт ли минимальный ограничительный
прямоугольник g1 прямоугольником
g2 . Это проверяет противоположные отношения как
MBRCovers() .
MBRCoveredBy()
и MBRCovers()
обрабатывают параметры и возвращают значение следующим образом:
mysql> SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql> SET @g2 = ST_GeomFromText('Point(1 1)');
mysql> SELECT MBRCovers(@g1,@g2), MBRCoveredby(@g1,@g2);
+--------------------+-----------------------+
| MBRCovers(@g1,@g2) | MBRCoveredby(@g1,@g2) |
+--------------------+-----------------------+
| 1 | 0 |
+--------------------+-----------------------+
mysql> SELECT MBRCovers(@g2,@g1), MBRCoveredby(@g2,@g1);
+--------------------+-----------------------+
| MBRCovers(@g2,@g1) | MBRCoveredby(@g2,@g1) |
+--------------------+-----------------------+
| 0 | 1 |
+--------------------+-----------------------+
MBRCovers(g1
,g2 )
Возвращает 1 или 0, чтобы указать, покрывает ли минимальный
ограничительный прямоугольник g1 прямоугольник
g2 . Это проверяет противоположные отношения как
MBRCoveredBy() .
MBRDisjoint(g1
,g2 )
Возвращает 1 или 0, чтобы указать, являются ли несвязными (не
пересекаются) минимальные ограничительные прямоугольники двух конфигураций
g1 и g2 .
MBREquals(g1
, g2 )
Возвращает 1 или 0, чтобы указать, являются ли минимальные ограничительные
прямоугольники двух конфигураций g1 и g2
тем же самым.
MBRIntersects(g1
,g2 )
Возвращает 1 или 0, чтобы указать, пересекаются ли
минимальные ограничительные прямоугольники двух конфигураций
g1 и g2 .
MBROverlaps(g1
,g2 )
Возвращает 1 или 0, чтобы указать, перекрываются ли
минимальные ограничительные прямоугольники двух конфигураций
g1 и g2 . Термин
перекрываются используется, если две конфигурации
пересекаются и их перекрестные результаты лежат в геометрии того же самого
измерения, но не равны любой из данных конфигураций.
MBRTouches(g1
,g2 )
Возвращает 1 или 0, чтобы указать, касаются ли
минимальные ограничительные прямоугольники двух конфигураций
g1 и g2 . Две конфигурации
касаются, если внутренности конфигураций не
пересекаются, но граница одних из конфигураций пересекает границу
или внутренности другой.
MBRWithin(g1
,g2 )
Возвращает 1 или 0, чтобы указать, находится ли минимальный ограничительный
прямоугольник g1 в пределах минимального
ограничительного прямоугольника g2 . Это проверяет
противоположные отношения как
MBRContains() .
mysql> SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql> SET @g2 = ST_GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
mysql> SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
+--------------------+--------------------+
| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
+--------------------+--------------------+
| 1 | 0 |
+--------------------+--------------------+
13.15.10.
Пространственные функции Geohash
Geohash система для того, чтобы закодировать широту и долготу произвольной
точности в текстовую строку. Значения Geohash строки, которые содержат только
символы, выбранные из "0123456789bcdefghjkmnpqrstuvwxyz" .
Функции в этом разделе включают манипуляции значениями geohash, которые
обеспечивают приложения способностями импорта и экспорта geohash-данных,
индексации и поиска geohash-значений.
ST_GeoHash(longitude
, latitude ,
max_length ) ,
ST_GeoHash(point
, max_length )
Возвращает строку geohash в наборе символов соединения и сопоставлении.
Результат NULL если какой-либо параметр NULL .
Ошибка происходит, если какой-либо параметр недопустим.
Для первого синтаксиса longitude
должно быть числом в диапазоне [-180, 180], а latitude
должно быть числом в диапазоне [-90, 90]. Для второго синтаксиса
требуется значение POINT , где координаты X и Y находятся в
допустимых диапазонах для долготы и широты, соответственно.
Получающаяся строка не больше max_length
символов, есть верхний предел 100. Строка могла бы быть короче, чем
max_length , потому что алгоритм, который создает
geohash, продолжается, пока не создаст строку, которая является или точным
представлением местоположения или max_length символов.
mysql> SELECT ST_GeoHash(180,0,10), ST_GeoHash(-180,-90,15);
+----------------------+-------------------------+
| ST_GeoHash(180,0,10) | ST_GeoHash(-180,-90,15) |
+----------------------+-------------------------+
| xbpbpbpbpb | 000000000000000 |
+----------------------+-------------------------+
ST_LatFromGeoHash(
geohash_str )
Возвращает широту из строкового значения geohash как значение
DOUBLE в диапазоне
[-90, 90]. Результат NULL , если какой-либо параметр
NULL . Ошибка происходит, если параметр недопустим.
Функция
ST_LatFromGeoHash() читает не больше, чем 433 символа из
geohash_str . Это представляет верхний предел информации
во внутреннем представлении координатных значений. Символы после 433
проигнорированы, даже если они незаконны и производят ошибку.
mysql> SELECT ST_LatFromGeoHash(ST_GeoHash(45,-20,10));
+------------------------------------------+
| ST_LatFromGeoHash(ST_GeoHash(45,-20,10)) |
+------------------------------------------+
| -20 |
+------------------------------------------+
ST_LongFromGeoHash(
geohash_str )
Возвращает долготу из строкового значения geohash как значение
DOUBLE в диапазоне
[-180, 180]. Результат NULL , если какой-либо параметр
NULL . Ошибка происходит, если параметр недопустим.
Замечания в описании
ST_LatFromGeoHash()
относительно максимального количества символов, обработанных из
параметра geohash_str параметр также относятся к
ST_LongFromGeoHash()
.
mysql> SELECT ST_LongFromGeoHash(ST_GeoHash(45,-20,10));
+-------------------------------------------+
| ST_LongFromGeoHash(ST_GeoHash(45,-20,10)) |
+-------------------------------------------+
| 45 |
+-------------------------------------------+
ST_PointFromGeoHash(geohash_str ,
srid )
Возвращает значение POINT , содержащее расшифрованное значение
geohash, данное в виде строки. Координаты X и Y точки это долгота в диапазоне
[-180, 180] и широта в диапазоне [-90, 90], соответственно.
srid это unsigned 32-bit integer. Результат
NULL , если какой-либо параметр NULL . Ошибка
происходит, если какой-либо параметр недопустим.
Замечания в описании
ST_LatFromGeoHash()
относительно максимального количества символов, обработанных из
geohash_str применимы и для
ST_PointFromGeoHash()
.
mysql> SET @gh = ST_GeoHash(45,-20,10);
mysql> SELECT ST_AsText(ST_PointFromGeoHash(@gh,0));
+---------------------------------------+
| ST_AsText(ST_PointFromGeoHash(@gh,0)) |
+---------------------------------------+
| POINT(45 -20) |
+---------------------------------------+
13.15.11.
Пространственные функции GeoJSON
Этот раздел описывает функции для того, чтобы преобразовать между
документами GeoJSON и пространственными значениями. GeoJSON открытый
стандарт для того, чтобы закодировать геометрические/географические
особенности. Для получения дополнительной информации см.
http://geojson.org.
Функции, обсужденные здесь, следуют спецификации GeoJSON revision 1.0.
GeoJSON поддерживает те же самые геометрические/географические типы
данных, что и MySQL. Объекты Feature и FeatureCollection
не поддержаны, за исключением того, что объекты геометрии извлечены из них.
Поддержка CRS ограничена значениями, которые идентифицируют SRID.
MySQL также поддерживает тип данных JSON
и ряд SQL функций для работы с ним. См. разделы
12.6 и
13.16.
ST_AsGeoJSON(g
[, max_dec_digits [,
options ]])
Производит объект GeoJSON из геометрии g .
У строки объекта есть набор символов соединения и сопоставление.
max_dec_digits , если определено, ограничивает число
десятичных цифр для координат. Если не определен, этот параметр по умолчанию
установлен к его максимальному значению 232-1. Минимум 0.
options , если определено, битовая маска. Следующая
таблица показывает разрешенные значения флага. Если у параметра геометрии
есть SRID 0, никакой объект CRS не произведен даже для тех значений флага,
которые его просят.
Значение флага | Смысл
|
0 | Никаких опций нет. Это значение по
умолчанию, если options не задано. |
1 | Добавить ограничивающий прямоугольник к выводу.
|
2 | Добавить короткий формат CRS URN к выводу.
Формат значения по умолчанию: короткий формат
(EPSG:srid ). |
4 | Добавить длинный формат CRS URN к выводу
(urn:ogc:def:crs:EPSG::srid ).
Этот флаг переопределяет 2. Например, значения опции 5 и 7 означают то же
самое (добавить ограничивающий прямоугольник и длинный формат CRS URN).
|
Если какой-либо параметр NULL , возвращаемое значение
NULL . Если любой параметр не-NULL
недопустим, ошибка происходит.
mysql> SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)'),2);
+-------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)'),2) |
+-------------------------------------------------------------+
| {"type": "Point", "coordinates": [11.11, 12.22]} |
+-------------------------------------------------------------+
ST_GeomFromGeoJSON(str [,
options [, srid ]])
Разбирает строку str , представляющую объект
GeoJSON и возвращает геометрию.
options , если дано, описывает, как обработать
документы GeoJSON, которые содержат конфигурации с координатными измерениями
выше 2. Следующая таблица показывает разрешенные значения
options .
Значение опции | Смысл
|
1 |
Отклонить документ и произвести ошибку. Это значение по умолчанию, если
options не определен. |
2, 3, 4 |
Принять документ и обрезать координаты для более
высоких координатных измерений. |
Значения options 2, 3 и 4 в настоящее время
оказывают то же самое влияние. Если конфигурации с координатными измерениями
выше 2 будут поддержаны в будущем, то эти значения окажут различные влияния.
Параметр srid , если дан, должен быть
32-bit unsigned integer. Если не дан, у возвращаемого значения
геометрии есть SRID 4326.
У геометрии GeoJSON, объектов feature и feature collection может быть
свойство crs . Разборы функции парсинга под названием
CRS URN в пространствах имен urn:ogc:def:crs:EPSG::srid
и EPSG:srid , но не
CRS, данный как объект ссылки. Кроме того,
urn:ogc:def:crs:OGC:1.3:CRS84 признан как SRID 4326.
Если у объекта есть CRS, который не понят, ошибка происходит, за исключением
того, что если дополнительный параметр srid дан,
любой CRS проигнорирован, даже если это недопустимо.
Как определено в спецификации GeoJSON,
парсинг является чувствительным к регистру для члена type
ввода GeoJSON (Point , LineString и т.д.).
Спецификация ничего не определяет относительно чувствительности к регистру
для другого парсинга, который в MySQL не является чувствительным к регистру.
Если какой-либо параметр NULL , возвращаемое значение
NULL . Если любой параметр не-NULL
недопустим, происходит ошибка.
Этот пример показывает результат парсинга для простого объекта GeoJSON:
mysql> SET @json = '{ "type": "Point", "coordinates": [102.0, 0.0]}';
mysql> SELECT ST_AsText(ST_GeomFromGeoJSON(@json));
+--------------------------------------+
| ST_AsText(ST_GeomFromGeoJSON(@json)) |
+--------------------------------------+
| POINT(102 0) |
+--------------------------------------+
13.15.12.
Вспомогательные пространственные функции
Функции в этом разделе обеспечивают вспомогательные операции
на значениях геометрии.
ST_Distance_Sphere(
g1 , g2 [,radius
])
Возвращает минимальное сферическое расстояние между двумя точками и/или
мультиточками на сфере, в метрах или NULL ,
если какой-либо параметр геометрии NULL или пустой.
Вычисления используют сферическую землю и конфигурируемый радиус.
Дополнительный параметр radius должен быть дан в
метрах. Если опущен, радиус значения по умолчанию составляет 6370986 метров.
Ошибка ER_WRONG_ARGUMENTS
происходит, если параметр radius
присутствует, но не положительный.
Параметры геометрии должны состоять из пунктов, которые определяют
(долгота, широта) координатные значения:
Поддержанные комбинации параметра (Point ,
Point ), (Point ,
MultiPoint ), и (MultiPoint , Point ).
Ошибка
ER_GIS_UNSUPPORTED_ARGUMENT происходит для других комбинаций.
Ошибка
ER_GIS_INVALID_DATA происходит, если какой-либо параметр геометрии
не допустимая строка геометрии.
mysql> SET @pt1 = ST_GeomFromText('POINT(0 0)');
mysql> SET @pt2 = ST_GeomFromText('POINT(180 0)');
mysql> SELECT ST_Distance_Sphere(@pt1, @pt2);
+--------------------------------+
| ST_Distance_Sphere(@pt1, @pt2) |
+--------------------------------+
| 20015042.813723423 |
+--------------------------------+
ST_IsValid(g
)
Проверяет, допустима ли геометрия, как определено спецификацией OGC.
ST_IsValid()
Возвращает 1, если параметр допустимая строка геометрии и геометрически
допустим, 0, если параметр не допустимая строка геометрии или не
геометрически допустим, NULL если параметр NULL .
Единственная допустимая пустая геометрия представлена в форме пустого
значения набора геометрии.
ST_IsValid()
возвращает 1 в этом случае.
ST_IsValid()
работает только для декартовой системы координат и требует параметра
геометрии с SRID 0. Иначе будет ошибка
ER_WRONG_ARGUMENTS
.
mysql> SET @ls1 = ST_GeomFromText('LINESTRING(0 0)');
mysql> SET @ls2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
mysql> SELECT ST_IsValid(@ls1);
+------------------+
| ST_IsValid(@ls1) |
+------------------+
| 0 |
+------------------+
mysql> SELECT ST_IsValid(@ls2);
+------------------+
| ST_IsValid(@ls2) |
+------------------+
| 1 |
+------------------+
ST_MakeEnvelope(
pt1 , pt2 )
Возвращает прямоугольник, который формирует конверт вокруг двух точек.
Возвращенная геометрия Point ,
LineString , Polygon или NULL ,
если какой-либо параметр NULL .
Вычисления сделаны, используя декартовую систему координат, а не на сфере,
сфероиде или Земле.
Учитывая два пункта pt1 и pt2 ,
ST_MakeEnvelope()
создает геометрию результата в абстрактном плане так:
У геометрии результата есть SRID 0.
ST_MakeEnvelope()
требует параметры Point геометрии с SRID 0. Иначе
будет ошибка
ER_WRONG_ARGUMENTS .
Ошибка
ER_GIS_INVALID_DATA происходит, если какой-либо параметр не
допустимая строка геометрии, или если какое-либо координатное значение двух
пунктов бесконечно (то есть, NaN).
mysql> SET @pt1 = ST_GeomFromText('POINT(0 0)');
mysql> SET @pt2 = ST_GeomFromText('POINT(1 1)');
mysql> SELECT ST_AsText(ST_MakeEnvelope(@pt1, @pt2));
+----------------------------------------+
| ST_AsText(ST_MakeEnvelope(@pt1, @pt2)) |
+----------------------------------------+
| POLYGON((0 0,1 0,1 1,0 1,0 0)) |
+----------------------------------------+
ST_Simplify(g
, max_distance )
Упрощает геометрию, используя алгоритм Дугласа-Пеукера и возвращает
упрощенное значение того же самого типа или NULL , если
какой-либо параметр NULL .
Геометрия может быть любым типом геометрии, хотя алгоритм Дугласа-Пеукера,
возможно, не фактически обрабатывает каждый тип. Набор геометрии обработан,
давая его компоненты один за другим алгоритму упрощения и возвращенные
конфигурации помещены в набор геометрии как результат.
Параметр max_distance расстояние (в единицах
входных координат) вершины к другим сегментам, которые будут удалены. Вершины
в пределах этого расстояния удалены. Ошибка
ER_WRONG_ARGUMENTS
происходит, если max_distance не положителен
или является NaN.
Согласно Boost.Geometry, конфигурации могли бы стать недопустимыми в
результате процесса упрощения, и процесс мог бы создать самопересечения. Если
Вы хотите проверить законность результата, передайте его
ST_IsValid() .
Ошибка
ER_GIS_INVALID_DATA происходит, если параметр геометрии не
допустимая строка геометрии.
mysql> SET @g = ST_GeomFromText('LINESTRING(0 0,0 1,1 1,1 2,2 2,2 3,3 3)');
mysql> SELECT ST_AsText(ST_Simplify(@g, 0.5));
+---------------------------------+
| ST_AsText(ST_Simplify(@g, 0.5)) |
+---------------------------------+
| LINESTRING(0 0,0 1,1 1,2 3,3 3) |
+---------------------------------+
mysql> SELECT ST_AsText(ST_Simplify(@g, 1.0));
+---------------------------------+
| ST_AsText(ST_Simplify(@g, 1.0)) |
+---------------------------------+
| LINESTRING(0 0,3 3) |
+---------------------------------+
mysql> SELECT ST_AsText(ST_Simplify(@g));
ST_Validate(g
)
Утверждает геометрию согласно спецификации OGC.
ST_Validate()
возвращает геометрию, если это допустимая строка геометрии и геометрически
допустимо, NULL , если параметр не допустимая строка геометрии,
геометрически недопустим или NULL .
Геометрия может быть допустимой строкой (значение WKB плюс SRID), но
геометрически недопустимой. Например, этот многоугольник геометрически
недопустим: POLYGON((0 0, 0 0, 0 0, 0 0, 0 0)) .
ST_Validate()
может использоваться, чтобы отфильтровать недопустимые данные о геометрии
для приложений, которые требуют более точных результатов, не
испорченных недопустимыми данными.
Если параметр геометрии допустим, он возвращен как есть, за исключением
того, что если вводный Polygon или MultiPolygon
имеет кольца, они полностью изменены прежде, чем проверить на законность.
Если геометрия допустима, значение с полностью
измененными кольцами возвращено.
Единственная допустимая пустая геометрия представлена в форме пустого
значения набора геометрии.
ST_Validate()
возвращает это непосредственно без дальнейших проверок в этом случае.
ST_Validate()
работает только для декартовой системы координат и требуют параметра
геометрии с SRID 0. Иначе произойдет ошибка
ER_WRONG_ARGUMENTS
.
mysql> SET @ls1 = ST_GeomFromText('LINESTRING(0 0)');
mysql> SET @ls2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
mysql> SELECT ST_AsText(ST_Validate(@ls1));
+------------------------------+
| ST_AsText(ST_Validate(@ls1)) |
+------------------------------+
| NULL |
+------------------------------+
mysql> SELECT ST_AsText(ST_Validate(@ls2));
+------------------------------+
| ST_AsText(ST_Validate(@ls2)) |
+------------------------------+
| LINESTRING(0 0,1 1) |
+------------------------------+
13.16. Функции JSON
Функции, описанные в этом разделе, выполняют операции на значениях JSON.
Для обсуждения типа данных JSON
и дополнительных примеров, показывающих, как использовать эти функции, см.
раздел 12.6.
Для функций, которые берут параметр JSON,
происходит ошибка, если параметр не допустимое значение JSON.
Ряд пространственных функций для того, чтобы воздействовать на значения
GeoJSON также доступен. См.
раздел 13.15.11.
13.16.1. Функции JSON (обзор)
Таблица 13.20. Функции JSON
MySQL 8.0.1 и более поздний поддерживает две совокупных функции JSON
JSON_ARRAYAGG() и
JSON_OBJECTAGG()
. См. раздел 13.19
для их описания.
13.16.2.
Функции, которые создают значения JSON
Функции в этом разделе составляют значения JSON из составляющих элементов.
JSON_ARRAY([val
[, val ] ...])
Оценивает (возможно пустой) список значений и возвращает массив JSON,
содержащий те значения.
mysql> SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME());
+---------------------------------------------+
| JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME()) |
+---------------------------------------------+
| [1, "abc", null, true, "11:30:24.000000"] |
+---------------------------------------------+
JSON_OBJECT([key
, val [, key ,
val ] ...])
Оценивает (возможно пустой) список пар ключа/значения и возвращает объект
JSON, содержащий те пары. Ошибка происходит, если какое-либо ключевое имя
NULL или число параметров является странным.
mysql> SELECT JSON_OBJECT('id', 87, 'name', 'carrot');
+-----------------------------------------+
| JSON_OBJECT('id', 87, 'name', 'carrot') |
+-----------------------------------------+
| {"id": 87, "name": "carrot"} |
+-----------------------------------------+
JSON_QUOTE(json_val
)
Заключает строку в кавычки как значение JSON
символами двойной кавычки и экранируя внутренние кавычки и другие символы,
возвращая результат как строку utf8mb4 .
Возвращает NULL , если параметр NULL .
Эта функция, как правило, используется, чтобы произвести допустимую строку
JSON для включения в пределах документа JSON.
Определенные специальные символы оставляют с наклонными чертами влево как
escape-последовательности, показанные в
таблице 13.21.
mysql> SELECT JSON_QUOTE('null'), JSON_QUOTE('"null"');
+--------------------+----------------------+
| JSON_QUOTE('null') | JSON_QUOTE('"null"') |
+--------------------+----------------------+
| "null" | "\"null\"" |
+--------------------+----------------------+
mysql> SELECT JSON_QUOTE('[1, 2, 3]');
+-------------------------+
| JSON_QUOTE('[1, 2, 3]') |
+-------------------------+
| "[1, 2, 3]" |
+-------------------------+
Вы можете также получить значения JSON, конвертируя значения других типов
в JSON с помощью
CAST(value AS
JSON) .
13.16.3. Функции поиска значений JSON
Функции в этом разделе выполняют операции поиска на значениях JSON,
чтобы извлечь данные из них, сообщить, существуют ли данные в их пределах или
сообщить о пути к данным в их пределах.
JSON_CONTAINS(
json_doc , val [,
path ])
Возвращает 0 или 1, чтобы указать, содержится ли определенное значение в
цели документа JSON или, если задан параметр path ,
в определенном пути в пределах целевого документа. Возвращает
NULL , если какой-либо параметр NULL
или параметр пути не идентифицирует раздел целевого документа. Ошибка
происходит, если или параметр документа не допустимый документ JSON или
параметр path недопустимое выражение пути или содержит
подстановочный знак * (или ** ).
Чтобы проверить только, существуют ли какие-либо данные в пути, надо
использовать
JSON_CONTAINS_PATH() .
Следующие правила определяют логику:
Скаляр кандидата содержится в целевом скаляре, если и только если
они сопоставимы и равны. Два скалярных значения сопоставимы, если у них есть
те же самые типы JSON_TYPE()
, за исключением того, что значения типов INTEGER и
DECIMAL также сопоставимы друг с другом.
- Массив кандидата содержится в целевом массиве, если и только если каждый
элемент в кандидате содержится в некотором элементе цели.
- Немассив кандидата содержится в целевом массиве, если и только если
кандидат содержится в некотором элементе цели.
- Объект кандидата содержится в целевом объекте, если и только если для
каждого ключа в кандидате есть ключ с тем же самым именем в цели, и значение,
связанное с возможным ключом, содержится в значении,
связанном с целевым ключом.
Иначе значение кандидата не содержится в целевом документе.
mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
mysql> SET @j2 = '1';
mysql> SELECT JSON_CONTAINS(@j, @j2, '$.a');
+-------------------------------+
| JSON_CONTAINS(@j, @j2, '$.a') |
+-------------------------------+
| 1 |
+-------------------------------+
mysql> SELECT JSON_CONTAINS(@j, @j2, '$.b');
+-------------------------------+
| JSON_CONTAINS(@j, @j2, '$.b') |
+-------------------------------+
| 0 |
+-------------------------------+
mysql> SET @j2 = '{"d": 4}';
mysql> SELECT JSON_CONTAINS(@j, @j2, '$.a');
+-------------------------------+
| JSON_CONTAINS(@j, @j2, '$.a') |
+-------------------------------+
| 0 |
+-------------------------------+
mysql> SELECT JSON_CONTAINS(@j, @j2, '$.c');
+-------------------------------+
| JSON_CONTAINS(@j, @j2, '$.c') |
+-------------------------------+
| 1 |
+-------------------------------+
JSON_CONTAINS_PATH(
json_doc ,
one_or_all , path [,
path ] ...)
Возвращает 0 или 1, чтобы указать, содержит ли документ JSON
данные в заданном пути или путях. Возвращает NULL ,
если какой-либо параметр NULL . Ошибка происходит, если
параметр json_doc не допустимый документ JSON, любой
параметр path не допустимое выражение пути или
one_or_all не
'one' или 'all' .
Чтобы проверить на определенное значение в пути, надо использовать
JSON_CONTAINS() .
Возвращаемое значение 0, если никакой указанный путь не существует в
пределах документа. Иначе, возвращаемое значение зависит от параметра
one_or_all :
mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e');
+---------------------------------------------+
| JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e') |
+---------------------------------------------+
| 1 |
+---------------------------------------------+
mysql> SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e');
+---------------------------------------------+
| JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e') |
+---------------------------------------------+
| 0 |
+---------------------------------------------+
mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.c.d');
+----------------------------------------+
| JSON_CONTAINS_PATH(@j, 'one', '$.c.d') |
+----------------------------------------+
| 1 |
+----------------------------------------+
mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a.d');
+----------------------------------------+
| JSON_CONTAINS_PATH(@j, 'one', '$.a.d') |
+----------------------------------------+
| 0 |
+----------------------------------------+
JSON_EXTRACT(
json_doc ,
path [, path ] ...)
Возвращает данные из документа JSON,
выбранные из частей документа, соответствующих path .
Возвращает NULL если какой-либо параметр NULL или
никакие пути не определяют местонахождение значения в документе.
Ошибка происходит, если параметр json_doc не допустимый
документ JSON или любой параметр path не
допустимое выражение пути.
Возвращаемое значение состоит из всех значений, соответствующих
path . Если возможно, что те параметры могли возвратить
много значений, соответствующие значения автоматически оформлены как массив,
в порядке, соответствующем путям, которые произвели их.
Иначе, возвращаемое значение единственное соответствующее.
mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');
+--------------------------------------------+
| JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]') |
+--------------------------------------------+
| 20 |
+--------------------------------------------+
mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
+----------------------------------------------------+
| JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]') |
+----------------------------------------------------+
| [20, 10] |
+----------------------------------------------------+
mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');
+-----------------------------------------------+
| JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]') |
+-----------------------------------------------+
| [30, 40] |
+-----------------------------------------------+
MySQL поддерживает оператор
->
как сокращение для для этой функции при использовании с 2 параметрами, где
левая сторона идентификатор столбца JSON
(не выражение) и правая сторона является путем JSON, который
будет соответствующим в пределах столбца.
column
->path
Оператор ->
служит псевдонимом для
JSON_EXTRACT() , когда функция используется с двумя параметрами,
идентификатор столбца слева и путь JSON справа, который оценен против
документа JSON (значение столбца). Вы можете использовать такие выражения
вместо идентификаторов столбца везде, где они происходят в запросах SQL.
Два запроса SELECT ,
показанные здесь, производят тот же самый вывод:
mysql> SELECT c, JSON_EXTRACT(c, "$.id"), g FROM jemp
> WHERE JSON_EXTRACT(c, "$.id") > 1
> ORDER BY JSON_EXTRACT(c, "$.name");
+-------------------------------+-----------+------+
| c | c->"$.id" | g |
+-------------------------------+-----------+------+
| {"id": "3", "name": "Barney"} | "3" | 3 |
| {"id": "4", "name": "Betty"} | "4" | 4 |
| {"id": "2", "name": "Wilma"} | "2" | 2 |
+-------------------------------+-----------+------+
3 rows in set (0.00 sec)
mysql> SELECT c, c->"$.id", g FROM jemp
> WHERE c->"$.id" > 1
> ORDER BY c->"$.name";
+-------------------------------+-----------+------+
| c | c->"$.id" | g |
+-------------------------------+-----------+------+
| {"id": "3", "name": "Barney"} | "3" | 3 |
| {"id": "4", "name": "Betty"} | "4" | 4 |
| {"id": "2", "name": "Wilma"} | "2" | 2 |
+-------------------------------+-----------+------+
3 rows in set (0.00 sec)
Эта функциональность не ограничена SELECT ,
как показано здесь:
mysql> ALTER TABLE jemp ADD COLUMN n INT;
Query OK, 0 rows affected (0.68 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> UPDATE jemp SET n=1 WHERE c->"$.id" = "4";
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT c, c->"$.id", g, n FROM jemp
> WHERE JSON_EXTRACT(c, "$.id") > 1
> ORDER BY c->"$.name";
+-------------------------------+-----------+------+------+
| c | c->"$.id" | g | n |
+-------------------------------+-----------+------+------+
| {"id": "3", "name": "Barney"} | "3" | 3 | NULL |
| {"id": "4", "name": "Betty"} | "4" | 4 | 1 |
| {"id": "2", "name": "Wilma"} | "2" | 2 | NULL |
+-------------------------------+-----------+------+------+
3 rows in set (0.00 sec)
mysql> DELETE FROM jemp WHERE c->"$.id" = "4";
Query OK, 1 row affected (0.04 sec)
mysql> SELECT c, c->"$.id", g, n FROM jemp
> WHERE JSON_EXTRACT(c, "$.id") > 1
> ORDER BY c->"$.name";
+-------------------------------+-----------+------+------+
| c | c->"$.id" | g | n |
+-------------------------------+-----------+------+------+
| {"id": "3", "name": "Barney"} | "3" | 3 | NULL |
| {"id": "2", "name": "Wilma"} | "2" | 2 | NULL |
+-------------------------------+-----------+------+------+
2 rows in set (0.00 sec)
Это также работает со значениями массива JSON, как показано здесь:
mysql> CREATE TABLE tj10 (a JSON, b INT);
Query OK, 0 rows affected (0.26 sec)
mysql> INSERT INTO tj10
> VALUES ("[3,10,5,17,44]", 33), ("[3,10,5,17,[22,44,66]]", 0);
Query OK, 1 row affected (0.04 sec)
mysql> SELECT a->"$[4]" FROM tj10;
+--------------+
| a->"$[4]" |
+--------------+
| 44 |
| [22, 44, 66] |
+--------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM tj10 WHERE a->"$[0]" = 3;
+------------------------------+---+
| a | b |
+------------------------------+---+
| [3, 10, 5, 17, 44] |33 |
| [3, 10, 5, 17, [22, 44, 66]] | 0 |
+------------------------------+---+
2 rows in set (0.00 sec)
Поддержаны вложенные массивы. Использование выражения
-> оценивается какe NULL ,
если никакой ключ соответствия не найден в цели документа JSON,
как показано здесь:
mysql> SELECT * FROM tj10 WHERE a->"$[4][1]" IS NOT NULL;
+------------------------------+---+
| a | b |
+------------------------------+---+
| [3, 10, 5, 17, [22, 44, 66]] | 0 |
+------------------------------+---+
mysql> SELECT a->"$[4][1]" FROM tj10;
+--------------+
| a->"$[4][1]" |
+--------------+
| NULL |
| 44 |
+--------------+
2 rows in set (0.00 sec)
Это то же самое поведение, как в таких случаях,
используя JSON_EXTRACT() :
mysql> SELECT JSON_EXTRACT(a, "$[4][1]") FROM tj10;
+----------------------------+
| JSON_EXTRACT(a, "$[4][1]") |
+----------------------------+
| NULL |
| 44 |
+----------------------------+
2 rows in set (0.00 sec)
column
->>path
Это улучшенный, закрывающий кавычки оператор извлечения. Принимая во
внимание, что оператор -> просто извлекает значение,
->> кроме того, закрывает кавычки в извлеченном
результате. Другими словами, для данного значения столбца
JSON column
и выражение пути path
следующие три выражения возвращают то же самое значение:
Оператор ->> может использоваться везде, где
JSON_UNQUOTE(JSON_EXTRACT()) был бы позволен. Это включает (но
не ограничено) списки SELECT , предложения WHERE и
HAVING , определения ORDER BY и GROUP BY
.
Следующие запросы демонстрируют некоторые эквиваленты оператора
->> с другими выражениями в клиенте
mysql:
mysql> SELECT * FROM jemp WHERE g > 2;
+-------------------------------+---+
| c | g |
+-------------------------------+---+
| {"id": "3", "name": "Barney"} | 3 |
| {"id": "4", "name": "Betty"} | 4 |
+-------------------------------+---+
2 rows in set (0.01 sec)
mysql> SELECT c->'$.name' AS name FROM jemp WHERE g > 2;
+----------+
| name |
+----------+
| "Barney" |
| "Betty" |
+----------+
2 rows in set (0.00 sec)
mysql> SELECT JSON_UNQUOTE(c->'$.name') AS name
-> FROM jemp WHERE g > 2;
+--------+
| name |
+--------+
| Barney |
| Betty |
+--------+
2 rows in set (0.00 sec)
mysql> SELECT c->>'$.name' AS name
-> FROM jemp WHERE g > 2;
+--------+
| name |
+--------+
| Barney |
| Betty |
+--------+
2 rows in set (0.00 sec)
Этот оператор может также использоваться с массивами JSON,
как показано здесь:
mysql> CREATE TABLE tj10 (a JSON, b INT);
Query OK, 0 rows affected (0.26 sec)
mysql> INSERT INTO tj10 VALUES
-> ('[3,10,5,"x",44]', 33),
-> ('[3,10,5,17,[22,"y",66]]', 0);
Query OK, 2 rows affected (0.04 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT a->"$[3]", a->"$[4][1]" FROM tj10;
+-----------+--------------+
| a->"$[3]" | a->"$[4][1]" |
+-----------+--------------+
| "x" | NULL |
| 17 | "y" |
+-----------+--------------+
2 rows in set (0.00 sec)
mysql> SELECT a->>"$[3]", a->>"$[4][1]" FROM tj10;
+------------+---------------+
| a->>"$[3]" | a->>"$[4][1]" |
+------------+---------------+
| x | NULL |
| 17 | y |
+------------+---------------+
2 rows in set (0.00 sec)
Как с ->
, оператор ->> всегда расширяется в выводе
EXPLAIN , как
следующий пример демонстрирует:
mysql> EXPLAIN SELECT c->>'$.name' AS name
-> FROM jemp WHERE g > 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: jemp
partitions: NULL
type: range
possible_keys: i
key: i
key_len: 5
ref: NULL
rows: 2
filtered: 100.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: /* select#1 */ select
json_unquote(json_extract(`jtest`.`jemp`.`c`,'$.name')) AS `name` from
`jtest`.`jemp` where (`jtest`.`jemp`.`g` > 2)
1 row in set (0.00 sec)
Это подобно тому, как MySQL расширяет оператор
->
при тех же самых обстоятельствах.
JSON_KEYS(json_doc
[, path ])
Возвращает ключи из высокоуровневого значения объекта JSON как массив
JSON или если параметр path задан, высокоуровневые
ключи из выбранного пути. Возвращает NULL , если какой-либо
параметр NULL , параметр json_doc не
объект или path , если задан,
не определяет местонахождение объекта. Ошибка происходит, если параметр
json_doc не допустимый документ JSON или
path не допустимое выражение пути или содержит
подстановочный знак * или ** .
Массив результата пуст, если выбранный объект пуст. Если высокоуровневое
значение имеет вложенне подобъекты, возвращаемое значение не включает ключи
из тех подобъектов.
mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}');
+---------------------------------------+
| JSON_KEYS('{"a": 1, "b": {"c": 30}}') |
+---------------------------------------+
| ["a", "b"] |
+---------------------------------------+
mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b');
+----------------------------------------------+
| JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b') |
+----------------------------------------------+
| ["c"] |
+----------------------------------------------+
JSON_SEARCH(
json_doc ,
one_or_all , search_str [,
escape_char [,
path ] ...])
Возвращает путь к данной строке в пределах документа JSON. Возвращает
Returns NULL , если любой из параметров
json_doc , search_str или
path NULL , path не
существует в пределах документа, search_str
не найден. Ошибка происходит, если json_doc
не допустимый документ JSON, любой параметр path
не допустимое выражение пути, one_or_all не
'one' или 'all' или
escape_char не постоянное выражение.
Параметр one_or_all затрагивает
поиск следующим образом:
В пределах поисковой строки search_str символы
% и _ работают как в операторе
LIKE : %
соответствует любому числу символов (включая нулевые символы), а
_ соответствует точно одному символу.
Чтобы определить символ % или _
в строке поиска, предварите его символом ESC. Значение по умолчанию
\ , если параметр escape_char отсутствует
или NULL . Иначе
escape_char должен быть константой, которая пуста
или один символ.
Для обработки символа ESC, отличие от поведения
LIKE
состоит в том что символ ESC для
JSON_SEARCH()
должен быть оценен как константа во время компиляции, не только во время
выполнения. Например, если
JSON_SEARCH()
используется в готовом запросе и параметр escape_char
поставляется, используя ? , значение параметра могло бы быть
постоянным во время выполнения, но не во время компиляции.
mysql> SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
mysql> SELECT JSON_SEARCH(@j, 'one', 'abc');
+-------------------------------+
| JSON_SEARCH(@j, 'one', 'abc') |
+-------------------------------+
| "$[0]" |
+-------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', 'abc');
+-------------------------------+
| JSON_SEARCH(@j, 'all', 'abc') |
+-------------------------------+
| ["$[0]", "$[2].x"] |
+-------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', 'ghi');
+-------------------------------+
| JSON_SEARCH(@j, 'all', 'ghi') |
+-------------------------------+
| NULL |
+-------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10');
+------------------------------+
| JSON_SEARCH(@j, 'all', '10') |
+------------------------------+
| "$[1][0].k" |
+------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$');
+-----------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$') |
+-----------------------------------------+
| "$[1][0].k" |
+-----------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*]');
+--------------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$[*]') |
+--------------------------------------------+
| "$[1][0].k" |
+--------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$**.k');
+---------------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$**.k') |
+---------------------------------------------+
| "$[1][0].k" |
+---------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k');
+-------------------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k') |
+-------------------------------------------------+
| "$[1][0].k" |
+-------------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1]');
+--------------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$[1]') |
+--------------------------------------------+
| "$[1][0].k" |
+--------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]');
+-----------------------------------------------+
| JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]') |
+-----------------------------------------------+
| "$[1][0].k" |
+-----------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]');
+---------------------------------------------+
| JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]') |
+---------------------------------------------+
| "$[2].x" |
+---------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%a%');
+-------------------------------+
| JSON_SEARCH(@j, 'all', '%a%') |
+-------------------------------+
| ["$[0]", "$[2].x"] |
+-------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%');
+-------------------------------+
| JSON_SEARCH(@j, 'all', '%b%') |
+-------------------------------+
| ["$[0]", "$[2].x", "$[3].y"] |
+-------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]');
+---------------------------------------------+
| JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]') |
+---------------------------------------------+
| "$[0]" |
+---------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]');
+---------------------------------------------+
| JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]') |
+---------------------------------------------+
| "$[2].x" |
+---------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]');
+---------------------------------------------+
| JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]') |
+---------------------------------------------+
| NULL |
+---------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[1]');
+-------------------------------------------+
| JSON_SEARCH(@j, 'all', '%b%', '', '$[1]') |
+-------------------------------------------+
| NULL |
+-------------------------------------------+
mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[3]');
+-------------------------------------------+
| JSON_SEARCH(@j, 'all', '%b%', '', '$[3]') |
+-------------------------------------------+
| "$[3].y" |
+-------------------------------------------+
13.16.4.
Функции, которые изменяют значения JSON
Функции в этом разделе изменяют значения JSON и возвращают результат.
JSON_APPEND(
json_doc , path , val [,
path , val ] ...)
Эта функция была переименована в
JSON_ARRAY_APPEND()
.
JSON_ARRAY_APPEND(
json_doc ,
path , val [,
path , val ] ...)
Добавляет значения в конец обозначенных массивов в пределах документа
JSON и возвращает результат. Возвращает NULL , если какой-либо
параметр NULL . Ошибка происходит, если
json_doc не допустимый документ JSON или любой
параметр path не допустимое выражение пути или содержит
подстановочный знак * или ** .
Пары пути/значения оценены слева направо. Документ, представленный,
оценивая одну пару, становится новым значением, против которого
оценена следующая пара.
Если путь выбирает скаляр или значение объекта, то значение оформлено
в массив, и новое значение добавлено к тому массиву. Проигнорированы пары,
для которых путь не идентифицирует значения в документе JSON.
mysql> SET @j = '["a", ["b", "c"], "d"]';
mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1);
+----------------------------------+
| JSON_ARRAY_APPEND(@j, '$[1]', 1) |
+----------------------------------+
| ["a", ["b", "c", 1], "d"] |
+----------------------------------+
mysql> SELECT JSON_ARRAY_APPEND(@j, '$[0]', 2);
+----------------------------------+
| JSON_ARRAY_APPEND(@j, '$[0]', 2) |
+----------------------------------+
| [["a", 2], ["b", "c"], "d"] |
+----------------------------------+
mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1][0]', 3);
+-------------------------------------+
| JSON_ARRAY_APPEND(@j, '$[1][0]', 3) |
+-------------------------------------+
| ["a", [["b", 3], "c"], "d"] |
+-------------------------------------+
mysql> SET @j = '{"a": 1, "b": [2, 3], "c": 4}';
mysql> SELECT JSON_ARRAY_APPEND(@j, '$.b', 'x');
+------------------------------------+
| JSON_ARRAY_APPEND(@j, '$.b', 'x') |
+------------------------------------+
| {"a": 1, "b": [2, 3, "x"], "c": 4} |
+------------------------------------+
mysql> SELECT JSON_ARRAY_APPEND(@j, '$.c', 'y');
+--------------------------------------+
| JSON_ARRAY_APPEND(@j, '$.c', 'y') |
+--------------------------------------+
| {"a": 1, "b": [2, 3], "c": [4, "y"]} |
+--------------------------------------+
mysql> SET @j = '{"a": 1}';
mysql> SELECT JSON_ARRAY_APPEND(@j, '$', 'z');
+---------------------------------+
| JSON_ARRAY_APPEND(@j, '$', 'z') |
+---------------------------------+
| [{"a": 1}, "z"] |
+---------------------------------+
JSON_ARRAY_INSERT(
json_doc ,
path , val [,
path , val ] ...)
Обновляет документ JSON, вставляя в массив в пределах документа и
возвращая измененный документ. Возвращает NULL , если какой-либо
параметр NULL . Ошибка происходит, если
json_doc не допустимый документ JSON или любой параметр
path не допустимое выражение пути, содержит
подстановочный знак * или **
или не заканчивается идентификатором элемента массива.
Пары пути/значения оценены слева направо. Документ, представленный,
оценивая одну пару, становится новым значением, против которого
оценена следующая пара.
Проигнорированы пары, для которых путь не идентифицирует массив
в документе JSON. Если путь идентифицирует элемент массива, соответствующее
значение вставлено в той позиции элемента, смещая любые последующие значения
направо. Если путь идентифицирует позицию массива после конца массива,
значение вставлено в конце массива.
mysql> SET @j = '["a", {"b": [1, 2]}, [3, 4]]';
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x');
+------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[1]', 'x') |
+------------------------------------+
| ["a", "x", {"b": [1, 2]}, [3, 4]] |
+------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x');
+--------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[100]', 'x') |
+--------------------------------------+
| ["a", {"b": [1, 2]}, [3, 4], "x"] |
+--------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x');
+-----------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x') |
+-----------------------------------------+
| ["a", {"b": ["x", 1, 2]}, [3, 4]] |
+-----------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[2][1]', 'y');
+---------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[2][1]', 'y') |
+---------------------------------------+
| ["a", {"b": [1, 2]}, [3, "y", 4]] |
+---------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y');
+----------------------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y') |
+----------------------------------------------------+
| ["x", "a", {"b": [1, 2]}, [3, 4]] |
+----------------------------------------------------+
Более ранние модификации затрагивают позиции следующих элементов в
массиве, так что последующие пути в том же самом вызове
JSON_ARRAY_INSERT()
должны принять это во внимание. В заключительном примере второй
путь ничего не вставляет, потому что путь больше ничему не соответствует
после первой вставки.
JSON_INSERT(
json_doc , path , val [,
path , val ] ...)
Вставляет данные в документ JSON и возвращает результат. Возвращает
NULL , если какой-либо параметр NULL . Ошибка
происходит, если параметр json_doc не допустимый
документ JSON или любой параметр path не допустимое
выражение пути или содержит подстановочный знак
* или ** .
Пары пути/значения оценены слева направо. Документ, представленный,
оценивая одну пару, становится новым значением, против которого
оценена следующая пара.
Пара пути/значения для существующего пути в документе проигнорирована и не
перезаписывает существующее значение документа. Пара пути/значения для
несуществующего пути в документе добавляет значение к документу, если путь
идентифицирует один из этих типов значений:
Иначе пара пути/значения для несуществующего пути в документе
проигнорирована и не имеет никакого эффекта.
Для сравнения
JSON_INSERT() ,
JSON_REPLACE() и
JSON_SET() см.
описание JSON_SET() .
mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
+----------------------------------------------------+
| JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') |
+----------------------------------------------------+
| {"a": 1, "b": [2, 3], "c": "[true, false]"} |
+----------------------------------------------------+
JSON_MERGE(json_doc
, json_doc [,
json_doc ] ...)
Сливает два или больше документа JSON и возвращает слитный результат.
Возвращает NULL , если какой-либо параметр NULL .
Ошибка происходит, если какой-либо параметр не допустимый документ JSON.
Слияние имеет место согласно следующим правилам:
mysql> SELECT JSON_MERGE('[1, 2]', '[true, false]');
+---------------------------------------+
| JSON_MERGE('[1, 2]', '[true, false]') |
+---------------------------------------+
| [1, 2, true, false] |
+---------------------------------------+
mysql> SELECT JSON_MERGE('{"name": "x"}', '{"id": 47}');
+-------------------------------------------+
| JSON_MERGE('{"name": "x"}', '{"id": 47}') |
+-------------------------------------------+
| {"id": 47, "name": "x"} |
+-------------------------------------------+
mysql> SELECT JSON_MERGE('1', 'true');
+-------------------------+
| JSON_MERGE('1', 'true') |
+-------------------------+
| [1, true] |
+-------------------------+
mysql> SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
+------------------------------------+
| JSON_MERGE('[1, 2]', '{"id": 47}') |
+------------------------------------+
| [1, 2, {"id": 47}] |
+------------------------------------+
JSON_REMOVE(json_doc
, path [, path ] ...)
Удаляет данные из документа JSON и возвращает результат.
Возвращает NULL , если какой-либо параметр NULL .
Ошибка происходит, если json_doc не допустимый документ
JSON или любой параметр path не допустимое выражение
пути или содержит подстановочный знак $ ,
* или ** .
Параметры path оценены слева направо. Документ,
представленный, оценивая один путь, становится новым значением, против
которого оценен следующий путь.
Это не ошибка, если элемент, который будет удален, не существует в
документе: в этом случае путь не затрагивает документ.
mysql> SET @j = '["a", ["b", "c"], "d"]';
mysql> SELECT JSON_REMOVE(@j, '$[1]');
+-------------------------+
| JSON_REMOVE(@j, '$[1]') |
+-------------------------+
| ["a", "d"] |
+-------------------------+
JSON_REPLACE(
json_doc , path ,
val [, path ,
val ] ...)
Заменяет существующие значения в документе JSON и возвращает результат.
Возвращает NULL , если какой-либо параметр NULL .
Ошибка происходит, если параметр json_doc не допустимый
документ JSONили любой path не допустимое выражение
пути или содержит подстановочный знак * или ** .
Пары пути/значения оценены слева направо. Документ, представленный,
оценивая одну пару, становится новым значением, против которого
оценена следующая пара.
Пара пути/значения для существующего пути в документе перезаписывает
существующее значение документа с новым значением. Пара пути/значения для
несуществующего пути в документе проигнорирована и не имеет никакого эффекта.
mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------+
| JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------+
| {"a": 10, "b": [2, 3]} |
+-----------------------------------------------------+
JSON_SET(json_doc
, path , val [,
path , val ] ...)
Вставляет или обновляет данные в документе JSON и возвращает результат.
Возвращает NULL , если какой-либо параметр NULL или
path , если дано, не определяет местонахождение объекта.
Ошибка происходит, если json_doc не допустимый документ
JSON или path не допустимое выражение пути или содержит
подстановочный знак * или ** .
Пары пути/значения оценены слева направо. Документ, представленный,
оценивая одну пару, становится новым значением, против которого
оценена следующая пара.
Пара пути/значения для существующего пути в документе перезаписывает
существующее значение документа новым значением. Пара пути/значения для
несуществующего пути в документе добавляет значение к документу, если
путь идентифицирует один из этих типов значений:
Иначе пара пути/значения для несуществующего пути в документе
проигнорирована и не имеет никакого эффекта.
Функции JSON_SET() ,
JSON_INSERT() и
JSON_REPLACE()
связаны:
Следующие примеры иллюстрируют эти различия, используя один путь, который
действительно существует в документе ($.a )
и другой, который не существует ($.c ):
mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
mysql> SELECT JSON_SET(@j, '$.a', 10, '$.c', '[true, false]');
+-------------------------------------------------+
| JSON_SET(@j, '$.a', 10, '$.c', '[true, false]') |
+-------------------------------------------------+
| {"a": 10, "b": [2, 3], "c": "[true, false]"} |
+-------------------------------------------------+
mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
+----------------------------------------------------+
| JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') |
+----------------------------------------------------+
| {"a": 1, "b": [2, 3], "c": "[true, false]"} |
+----------------------------------------------------+
mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------+
| JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------+
| {"a": 10, "b": [2, 3]} |
+-----------------------------------------------------+
JSON_UNQUOTE(val
)
Закрывает кавычки значения JSON и возвращает результат как строку в
utf8mb4 . Возвращает NULL , если параметр
NULL . Ошибка происходит, если значение начинается и
заканчивается двойными кавычками, но не является допустимой
буквальной строкой JSON.
В пределах строки у определенных последовательностей нет особого значения,
если включен режим SQL
NO_BACKSLASH_ESCAPES . Каждая из этих последовательностей
начинается с наклонной черты влево (\ ), известной как
escape character. MySQL признает
escape-последовательности, показанные в
таблице 13.21. Для всех других escape-последовательностей проигнорирована
наклонная черта влево. Таким образом, экранированный символ интерпретируется,
как будто его не экранировали. Например, \x соответствует
x . Эти последовательности являются чувствительными к регистру.
Например, \b интерпретируется как клавиша Backspace, но
\B интерпретируется только как B .
Таблица 13.21. Специальные символы escape-последовательностей
для JSON_UNQUOTE()
Escape-последовательность |
Символ, представленный последовательностью |
\" |
Двойная кавычка (" ) |
\b | backspace |
\f | Символ перевода формата |
\n | Новая строка |
\r | Возврат каретки |
\t | Табуляция |
\\ |
backslash (\ ) |
\uXXXX |
Байты UTF-8 для значения Unicode XXXX |
Два простых примера использования этой функции:
mysql> SET @j = '"abc"';
mysql> SELECT @j, JSON_UNQUOTE(@j);
+-------+------------------+
| @j | JSON_UNQUOTE(@j) |
+-------+------------------+
| "abc" | abc |
+-------+------------------+
mysql> SET @j = '[1, 2, 3]';
mysql> SELECT @j, JSON_UNQUOTE(@j);
+-----------+------------------+
| @j | JSON_UNQUOTE(@j) |
+-----------+------------------+
| [1, 2, 3] | [1, 2, 3] |
+-----------+------------------+
Следующий набор примеров показывает, как
JSON_UNQUOTE обрабатывает последовательности при выключенном и
включенном режиме
NO_BACKSLASH_ESCAPES :
mysql> SELECT @@sql_mode;
+------------+
| @@sql_mode |
+------------+
| |
+------------+
mysql> SELECT JSON_UNQUOTE('"\\t\\u0032"');
+------------------------------+
| JSON_UNQUOTE('"\\t\\u0032"') |
+------------------------------+
| 2 |
+------------------------------+
mysql> SET @@sql_mode = 'NO_BACKSLASH_ESCAPES';
mysql> SELECT JSON_UNQUOTE('"\\t\\u0032"');
+------------------------------+
| JSON_UNQUOTE('"\\t\\u0032"') |
+------------------------------+
| \t\u0032 |
+------------------------------+
mysql> SELECT JSON_UNQUOTE('"\t\u0032"');
+----------------------------+
| JSON_UNQUOTE('"\t\u0032"') |
+----------------------------+
| 2 |
+----------------------------+
13.16.5.
Функции, возвращающие атрибуты значений JSON
Функции в этом разделе возвращают признаки значений JSON.
JSON_DEPTH(json_doc
)
Возвращает максимальную глубину документа JSON. Возвращает
NULL , если параметр NULL . Ошибка происходит, если
параметр не допустимый документ JSON.
У пустого массива, пустого объекта или скалярного значения есть глубина 1.
У непустого массива, содержащего только элементы глубины 1 или непустой
объект, содержащий только значения глубины 1, есть глубина 2. Иначе у
документа JSON есть глубина больше 2.
mysql> SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true');
+------------------+------------------+--------------------+
| JSON_DEPTH('{}') | JSON_DEPTH('[]') | JSON_DEPTH('true') |
+------------------+------------------+--------------------+
| 1 | 1 | 1 |
+------------------+------------------+--------------------+
mysql> SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]');
+------------------------+------------------------+
| JSON_DEPTH('[10, 20]') | JSON_DEPTH('[[], {}]') |
+------------------------+------------------------+
| 2 | 2 |
+------------------------+------------------------+
mysql> SELECT JSON_DEPTH('[10, {"a": 20}]');
+-------------------------------+
| JSON_DEPTH('[10, {"a": 20}]') |
+-------------------------------+
| 3 |
+-------------------------------+
JSON_LENGTH(json_doc
[, path ])
Возвращает длину документа JSON или, если задан
path , длину значения в пределах документа,
идентифицированного путем. Возвращает NULL , если какой-либо
параметр NULL или path не идентифицирует
значение в документе. Ошибка происходит, если json_doc
не допустимый документ JSON или параметр path не
допустимое выражение пути или содержит подстановочный знак
* или ** .
Длина документа определена следующим образом:
Длина скаляра 1.
- Длина массива = число элементов массива.
- Длина объекта = число членов объекта.
- Длина не считает длину вложенных массивов или объектов.
mysql> SELECT JSON_LENGTH('[1, 2, {"a": 3}]');
+---------------------------------+
| JSON_LENGTH('[1, 2, {"a": 3}]') |
+---------------------------------+
| 3 |
+---------------------------------+
mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}');
+-----------------------------------------+
| JSON_LENGTH('{"a": 1, "b": {"c": 30}}') |
+-----------------------------------------+
| 2 |
+-----------------------------------------+
mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b');
+------------------------------------------------+
| JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b') |
+------------------------------------------------+
| 1 |
+------------------------------------------------+
JSON_TYPE(json_val
)
Возвращает строку utf8mb4 , указывающую на тип значения JSON:
mysql> SET @j = '{"a": [10, true]}';
mysql> SELECT JSON_TYPE(@j);
+---------------+
| JSON_TYPE(@j) |
+---------------+
| OBJECT |
+---------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a'));
+------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a')) |
+------------------------------------+
| ARRAY |
+------------------------------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[0]'));
+---------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a[0]')) |
+---------------------------------------+
| INTEGER |
+---------------------------------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[1]'));
+---------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a[1]')) |
+---------------------------------------+
| BOOLEAN |
+---------------------------------------+
JSON_TYPE()
возвращает NULL , если параметр NULL :
mysql> SELECT JSON_TYPE(NULL);
+-----------------+
| JSON_TYPE(NULL) |
+-----------------+
| NULL |
+-----------------+
Ошибка происходит, если параметр не допустимое значение JSON:
mysql> SELECT JSON_TYPE(1);
ERROR 3146 (22032): Invalid data type for JSON data in argument 1
to function json_type; a JSON string or JSON type is required.
Для не-NULL и неошибочного результата следующий список
описывает возможные возвращаемые значения
JSON_TYPE() :
Просто типы JSON:
OBJECT : Объекты JSON.
ARRAY : Массивы JSON.
BOOLEAN : Истинные и ложные литералы JSON.
NULL : Литерал JSON null.
Числовые типы:
Временные типы:
Строковые типы:
Двоичные типы:
Все другие типы:
JSON_VALID(val
)
Возвращает 0 или 1, чтобы указать, является ли значение допустимым
документом JSON. Возвращает NULL ,
если параметр NULL .
mysql> SELECT JSON_VALID('{"a": 1}');
+------------------------+
| JSON_VALID('{"a": 1}') |
+------------------------+
| 1 |
+------------------------+
mysql> SELECT JSON_VALID('hello'), JSON_VALID('"hello"');
+---------------------+-----------------------+
| JSON_VALID('hello') | JSON_VALID('"hello"') |
+---------------------+-----------------------+
| 0 | 1 |
+---------------------+-----------------------+
13.16.6. Синтаксис JSON Path
Многие из функций, описанных в предыдущих разделах, требуют выражения
пути, чтобы идентифицировать определенный элемент в документе JSON. Путь
состоит из контекста пути, сопровождаемого одной или более метками пути. Для
путей, используемых в MySQL-функциях JSON, контекст всегда документ, который
обрабатывается, представленный лидирующим символом $ . Метки пути
отделены символами точки (. ). Элементы в массивах представлены
[N ] , здесь N
неотрицательное целое число. Названия ключей должны быть заключены в двойные
кавычки строки или являться допустимыми идентификаторами ECMAScript
(см. http://www.ecma-international.org/ecma-262/5.1/#sec-7.6 ).
Выражения пути, как текст JSON, должны быть закодированы, используя наборы
символов ascii , utf8 или utf8mb4 .
Другие кодировки символов неявно приводятся к utf8mb4 .
Полный синтаксис выглядит так:
pathExpression :
scope [(pathLeg )*]
pathLeg :
member | arrayLocation | doubleAsterisk
member :
period ( keyName | asterisk )
arrayLocation :
leftBracket ( nonNegativeInteger | asterisk ) rightBracket
keyName :
ESIdentifier | doubleQuotedString
doubleAsterisk : '**'
period : '.'
asterisk : '*'
leftBracket : '['
rightBracket : ']'
Как отмечено ранее, в MySQL, контекст пути всегда обрабатываемый документ,
представленный как $ . Вы можете использовать '$'
как синоним для документа в выражениях пути JSON.
Некоторые реализации поддерживают ссылки столбца для контекстов путей
JSON, в настоящее время, MySQL не поддерживает их.
Подстановочные знаки * и **
используются следующим образом:
.* представляет значения всех членов в объекте.
[*] представляет значения всех элементов в массиве.
[prefix ]**suffix
представляет все пути, начинающиеся с prefix с
окончанием suffix . prefix
является дополнительным, в то время как suffix
обязателен. Путь, возможно, не заканчивается в ** .
Кроме того, путь, возможно, не содержит последовательность
*** .
Для примеров синтаксиса пути см. описания различных функций JSON, которые
берут пути в качестве параметров, например,
JSON_CONTAINS_PATH()
и JSON_REPLACE()
. Для примеров, которые включают использование * и
** см. описание функции
JSON_SEARCH() .
13.17.
Функции, используемые с глобальными транзакционными ID
Функции, описанные в этом разделе, используются с GTID-репликацией.
Важно иметь в виду, что все эти функции берут строковые представления наборов
GTID как параметры, наборы GTID должны всегда заключаться в кавычки,
когда используются с ними.
Союз двух наборов GTID просто их представления как строки, объединенные
запятой. Другими словами, Вы можете определить очень простую функцию для
того, чтобы получить союз двух наборов GTID, подобных создаваемому здесь:
CREATE FUNCTION GTID_UNION(g1 TEXT, g2 TEXT)
RETURNS TEXT DETERMINISTIC
RETURN CONCAT(g1,',',g2);
Таблица 13.22. Функции GTID
GTID_SUBSET(subset
,set )
Учитывая два набора ID subset и
set , вернет истину, если все GTID в
subset находятся также в
set . Иначе ложь.
Наборы GTID, используемые с этой функцией, представлены как строки, как
показано в следующих примерах:
mysql> SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1. row ***************************
GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'): 1
1 row in set (0.00 sec)
mysql> SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1. row ***************************
GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'): 1
1 row in set (0.00 sec)
mysql> SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1. row ***************************
GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'): 0
1 row in set (0.00 sec)
GTID_SUBTRACT(
set ,subset )
Учитывая два набора глобальных операционных ID
subset и set ,
возвращает только те GTID из set , которые
не находятся в subset .
Все наборы GTID, используемые с этой функцией, представлены как строки и
должны быть заключены в кавычки, как показано в этих примерах:
mysql> SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:21')\G
*************************** 1. row ***************************
GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:21'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:22-57
1 row in set (0.00 sec)
mysql> SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25')\G
*************************** 1. row ***************************
GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:26-57
1 row in set (0.00 sec)
mysql> SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
-> '3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24')\G
*************************** 1. row ***************************
GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24'): 3e11fa47-71ca-11e1-9e33-c80aa9429562:21-22:25-57
1 row in set (0.01 sec)
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(gtid_set [,
timeout ][,channel ])
Ждать, пока ведомый поток SQL не выполнит все транзакции, глобальные
операционные идентификаторы которых содержатся в
gtid_set (см.
раздел 19.1.3.1
для определения GTID sets), или timeout
секунд, смотря что происходит сначала. timeout
является дополнительным параметром: тайм-аут по умолчанию составляет 0
секунд, когда функция ждет, пока все транзакции в наборе GTID
не были выполнены.
Наборы GTID, используемые с этой функцией, представлены как строки и
должны быть заключены в кавычки как показано в следующем примере:
mysql> SELECT WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS('3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5');
-> 5
Возвращаемое значение число транзакционных событий, которые были запущены.
Если GTID-репликация не является активной (то есть, если значение
gtid_mode
OFF ), тогда это значение неопределено и таким образом
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() вернет NULL .
Если ведомое устройство не работает, эта функция
также возвращает NULL .
Опция channel позволяет Вам выбрать, к которому
каналу репликации относится функция. Если channel
не установлен и никакие каналы кроме канала по умолчанию не существуют,
функция относится к каналу по умолчанию. Если Вы используете много каналов
репликации, Вы должны определить channel , поскольку
иначе не известно, на который канал должна действовать функция. См.
раздел 19.2.3.
WAIT_FOR_EXECUTED_GTID_SET(gtid_set [,
timeout ])
WAIT_FOR_EXECUTED_GTID_SET() подобна
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() в том, что ждет, пока сервер
не выполнит все транзакции, глобальные операционные идентификаторы которых
содержатся в gtid_set , или пока не пройдет
timeout секунд. В отличие от
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() ,
WAIT_FOR_EXECUTED_GTID_SET() не принимает во внимание, работает
ли ведомое устройство или нет, и ошибка возвращена, если GTID-репликация
не включена вообще.
Кроме того, WAIT_FOR_EXECUTED_GTID_SET() возвращает только
статус запроса, где 0 представляет успех, 1, представляет тайм-аут, а любые
другие отказы возвращают сообщение об ошибке.
13.18. Прочие функции
Таблица 13.23. Прочие функции
ANY_VALUE(arg
)
Эта функция полезна для запросов GROUP BY , когда включен
режим SQL
ONLY_FULL_GROUP_BY , для случаев, когда MySQL
отклоняет запрос, который как Вы знаете, допустим по причинам, которые MySQL
не может определить. Функциональное возвращаемое значение и тип
те же самые, что и возвращаемое значение и тип его параметра, но
функциональный результат не проверен в режиме SQL
ONLY_FULL_GROUP_BY
.
Например, если name неиндексированный столбец, следующий
запрос терпит неудачу при включенном
ONLY_FULL_GROUP_BY
:
mysql> SELECT name, address, MAX(age) FROM t GROUP BY name;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP
BY clause and contains nonaggregated column 'mydb.t.address' which
is not functionally dependent on columns in GROUP BY clause; this
is incompatible with sql_mode=only_full_group_by
Отказ происходит потому, что address несоединенный столбец,
который не упомянут в столбцах GROUP BY и функционально не
зависит от них. В результате значение address для строк в
пределах каждой группы name недетерминировано. Есть много
способов заставить MySQL принимать запрос:
Измените таблицу, чтобы сделать name первичным ключом
или уникальным столбцом NOT NULL . Это позволяет MySQL
определить, что address функционально зависит от
name , то есть, address уникально определен через
name . Этот метод является неподходящим, если NULL
должен быть разрешен как допустимое значение name .
- Используйте
ANY_VALUE()
, чтобы обратиться к address :
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
В этом случае MySQL игнорирует недетерминизм значения
address в пределах каждой группы name
и принимает запрос. Это может быть полезно, если Вы просто не заботитесь,
какое значение несоединенного столбца выбрано для каждой группы.
ANY_VALUE()
не совокупная функция, в отличие от такой функций, как
SUM() или
COUNT() .
Это просто действует, чтобы подавить тест на недетерминизм.
- Выключите
ONLY_FULL_GROUP_BY . Это эквивалентно использованию
ANY_VALUE() с
включенным
ONLY_FULL_GROUP_BY , как описано в предыдущем элементе.
ANY_VALUE()
также полезна, если функциональная зависимость существует между столбцами, но
MySQL не может определить это. Следующий запрос допустим потому, что
age функционально зависит от группирующегося столбца
age-1 , но MySQL не может сказать это и отклоняет запрос при
включении
ONLY_FULL_GROUP_BY :
SELECT age FROM t GROUP BY age-1;
Чтобы заставить MySQL принимать запрос, надо использовать
ANY_VALUE() :
SELECT ANY_VALUE(age) FROM t GROUP BY age-1;
ANY_VALUE()
может использоваться для запросов, которые обращаются к совокупным функциям в
отсутствие предложения GROUP BY :
mysql> SELECT name, MAX(age) FROM t;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
#1 of SELECT list contains nonaggregated column 'mydb.t.name'; this
is incompatible with sql_mode=only_full_group_by
Без GROUP BY есть единственная группа и не определено,
которое значение name выбрать для группы.
ANY_VALUE()
говорит MySQL принимать запрос:
SELECT ANY_VALUE(name), MAX(age) FROM t;
Может случиться так, что из-за некоторого свойства набора определенных
данных, Вы знаете, что выбранный несоединенный столбец эффективно
функционально зависит от столбца в GROUP BY . Например,
приложение может провести в жизнь уникальность одного столбца относительно
другого. В этом случае использование
ANY_VALUE()
уву эффективно функционально зависимый столбец может иметь смысл.
BIN_TO_UUID(
binary_uuid ) ,
BIN_TO_UUID(
binary_uuid , swap_flag )
BIN_TO_UUID()
инверсия UUID_TO_BIN()
. Это преобразовывает двоичный UUID в строку UUID и возвращает результат.
Двоичное значение должно быть UUID как
VARBINARY(16) .
Возвращаемое значение строка utf8 из пяти шестнадцатеричных
чисел, разделенных тире. Для деталей об этом формате см. описание функции
UUID() . Если параметр
UUID NULL , возвращаемое значение NULL . Если
какой-либо параметр недопустим, ошибка происходит.
BIN_TO_UUID()
берет один или два параметра:
Форма с одним параметром берет двоичное значение UUID. У значения
UUID, как предполагается, части time-low и time-high не поменяны. Строковый
результат находится в том же самом порядке, как двоичной параметр.
- Форма с двумя параметрами берет двоичное значение UUID и значение флага:
Для примеров использования и информации о свопинге частей времени см.
функциональное описание
UUID_TO_BIN() .
DEFAULT(col_name
)
Возвращает значение по умолчанию для столбца таблицы. Ошибка происходит,
если у столбца нет никакого значения по умолчанию.
mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
FORMAT(X ,
D )
Форматирует число X в формат
'#,###,###.##' , округленный к D
десятичных разрядов и возвращает результат как строку. Для деталей см.
раздел 13.5.
GET_LOCK(str
,timeout )
Пытается получить блокировку с именем, данным строкой
str , с использованием тайм-аута
timeout секунд. Отрицательное значение
timeout означает бесконечный тайм-аут. Блокировка
исключительна. В то время, как они проводится одним сеансом, другие сеансы не
могут получить блокировку с тем же самым именем.
Возвращает 1 , если блокировка была получена успешно,
0 , если попытка провалена по тайм-ауту (например, потому что
другой клиент ранее заблокировал имя), или NULL , если ошибка
произошла (такая как исчерпывание памяти, или поток был уничтожен с
mysqladmin kill
).
Блокировка, полученная с
GET_LOCK() снята явно, выполняя
RELEASE_LOCK()
или неявно, когда Ваш сеанс заканчивается. Снятие блокировки может также
произойти с другим вызовом
GET_LOCK() :
GET_LOCK()
осуществлен, используя подсистему metadata locking (MDL). Многократные
одновременные блокировки могут быть приобретены и
GET_LOCK()
не снимает существующих блокировок. Для данного сеанса даже возможно
приобрести много блокировок с тем же самым именем. Другие сеансы не могут
приобрести блокировку с этим именем, пока сеанс приобретения не снимает все
свои блокировки для имени.
Блокировки, приобретенные
GET_LOCK()
появятся в таблице Performance Schema
metadata_locks .
Столбец OBJECT_TYPE сообщает USER LEVEL LOCK и
OBJECT_NAME имя блокировки. Кроме того, способность приобретения
многократных блокировок вводит возможность тупика среди клиентов. Когда это
происходит, сервер выбирает вызывающего и заканчивает его запрос приобретения
блокировки с ошибкой
ER_USER_LOCK_DEADLOCK . Эта ошибка не
заставляет транзакции откатываться.
Например, предположите, что Вы выполняете эти запросы:
SELECT GET_LOCK('lock1',10);
SELECT GET_LOCK('lock2',10);
SELECT RELEASE_LOCK('lock2');
SELECT RELEASE_LOCK('lock1');
Второй GET_LOCK()
приобретает вторую блокировку, и оба
RELEASE_LOCK()
вернут 1 (успех).
MySQL ограничивает максимальную длину названий блокировки 64 символами.
Блокировки, полученные с
GET_LOCK() не сняты, когда транзакции
закрываются или откатываются.
GET_LOCK()
может использоваться, чтобы осуществить блокировки приложения или
моделировать блокировки записи. Имена заблокированы на основе всего сервера.
Если имя было заблокировано в пределах одного сеанса,
GET_LOCK()
блокирует любой запрос другого сеанса для блокировки с тем же самым именем.
Это позволяет клиентам, которые договариваются о данном имени блокировки,
использовать имя, чтобы выполнить совместную консультативную блокировку.
Но знайте, что это также позволяет клиенту, который не является членом группы
сотрудничающих клиентов, заблокировать имя (неосторожно или сознательно) и
таким образом препятствовать тому, чтобы любой из сотрудничающих клиентов
блокировал это имя. Один способ уменьшить вероятность этого состоит в том,
чтобы использовать имена блокировки, которые являются определенными для базы
данных или приложения. Например, используйте названия блокировки формы
db_name.str или app_name.str .
Если много клиентов ждут блокировки, порядок, в котором они приобретут ее,
не определен. Приложения не должны предположить, что клиенты приобретут
блокировку в том же самом порядке, в каком подали запросы блокировки.
GET_LOCK()
опасна для основанной на запросе репликации. Предупреждение зарегистрировано,
если Вы используете эту функцию, когда
binlog_format
установлена в значение STATEMENT .
Со способностью приобретения многоих именованных блокировок в MySQL 5.7.5
для единственного запроса возможно приобрести большое
количество блокировок. Например:
INSERT INTO ... SELECT GET_LOCK(t1.col_name) FROM t1;
У этих типов запросов могут быть определенные отрицательные воздействия.
Например, если запрос выполнит только часть работы и откатится назад, то
блокировки, приобретенные до момента отказа, будут все еще существовать.
Кроме того, если важно, чтобы блокировки предоставили в определенном порядке,
знайте, что порядок набора результатов может отличаться, в зависимости от
плана выполнения, который выбирает оптимизатор. По этим причинам может быть
лучше ограничить приложения единственным требованием приобретения
блокировки за запрос.
Различный интерфейс блокировки доступен как плагин или как ряд
определяемых пользователем функций. Этот интерфейс обеспечивает пространства
имен блокировки и разные блокировки чтения и записи, в отличие от интерфейса,
обеспеченного GET_LOCK()
и связанных функций. Для деталей см.
раздел 26.3.1.
INET_ATON(expr
)
Учитывая представление сетевого адреса IPv4 как строки, возвращает целое
число, которое представляет числовое значение адреса в сетевом порядке байтов
(big endian). INET_ATON()
вернет NULL , если это не понимает свой параметр.
mysql> SELECT INET_ATON('10.0.5.9');
-> 167773449
INET_ATON()
возвращает или, возможно, не возвращает не-NULL
результат для кратких IP-адресов (таких, как '127.1' как
представление '127.0.0.1' ). Из-за этого
INET_ATON() не должна
использоваться для таких адресов.
Чтобы сохранить значения, произведенные
INET_ATON() ,
используйте столбец INT UNSIGNED , а не
INT , который со знаком.
Если Вы используете столбец со знаком, значения, соответствующие IP-адресам,
для которых первый октет больше 127, не могут быть сохранены правильно. См.
раздел 12.2.6.
INET_NTOA(expr
)
Учитывая числовой сетевой адрес IPv4 в сетевом порядке байтов, возвращает
строковое представление адреса как недвоичную строку в наборе символов
соединения. INET_NTOA()
возвращает NULL , если это не понимает свой параметр.
mysql> SELECT INET_NTOA(167773449);
-> '10.0.5.9'
INET6_ATON(expr
)
Учитывая сетевой адрес IPv6 или IPv4 как строку, возвращает
двоичную строку, которая представляет числовое значение адреса в сетевом
порядке байтов (big endian). Поскольку адреса числового формата IPv6 требуют
большего количества байтов чем самый большой тип целого числа, представление,
возвращенное этой функцией, имеет тип данных
VARBINARY :
VARBINARY(16) для IPv6
и VARBINARY(4) для
IPv4. Если параметр не допустимый адрес,
INET6_ATON() вернет
NULL .
Следующее использование в качестве примера
HEX() показывает результат
INET6_ATON()
в пригодной для печати форме:
mysql> SELECT HEX(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
-> 'FDFE0000000000005A55CAFFFEFA9089'
mysql> SELECT HEX(INET6_ATON('10.0.5.9'));
-> '0A000509'
INET6_ATON() имеет несколько ограничений на допустимые
параметры. Они даны в следующем списке наряду с примерами.
Чтобы преобразовать адрес IPv4 expr
представленный в числовой форме как значение
INT в адрес IPv6,
представленный в числовой форме как значение
VARBINARY ,
используйте это выражение:
INET6_ATON(INET_NTOA(expr ))
Например:
mysql> SELECT HEX(INET6_ATON(INET_NTOA(167773449)));
-> '0A000509'
INET6_NTOA(expr
)
Учитывая IPv6 или сетевой адрес IPv4, представленный в числовой форме как
двоичная строка, возвращает строковое представление адреса как недвоичная
строка в наборе символов соединения. Если параметр не допустимый адрес,
INET6_NTOA() вернет
NULL .
INET6_NTOA()
имеет эти свойства:
Это не использует функции операционной системы, чтобы выполнить
преобразования, таким образом выходная строка независима от платформы.
- У строки возврата есть максимальная длина 39 (4 x 8 + 7).
Учитывая это, запрос:
CREATE TABLE t AS SELECT INET6_NTOA(expr ) AS c1;
У получающейся таблицы было бы это определение:
CREATE TABLE t (c1 VARCHAR(39) CHARACTER SET utf8 DEFAULT NULL);
- Строка возврата использует строчные буквы для адресов IPv6.
mysql> SELECT INET6_NTOA(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
-> 'fdfe::5a55:caff:fefa:9089'
mysql> SELECT INET6_NTOA(INET6_ATON('10.0.5.9'));
-> '10.0.5.9'
mysql> SELECT INET6_NTOA(UNHEX('FDFE0000000000005A55CAFFFEFA9089'));
-> 'fdfe::5a55:caff:fefa:9089'
mysql> SELECT INET6_NTOA(UNHEX('0A000509'));
-> '10.0.5.9'
IS_FREE_LOCK(str
)
Проверяет, можно ли блокировку str
свободно использовать (то есть, не заблокирована ли она). Возвращает
1 , если блокировка свободна (никто не использует блокировку),
0 , если блокировка используется, и NULL , если
ошибка происходит (такая, как неправильный параметр).
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда переменная
binlog_format
установлена в значение STATEMENT .
IS_IPV4(expr
)
Возвращает 1, если параметр допустимый адрес IPv4, определенный
как строка, 0 иначе.
mysql> SELECT IS_IPV4('10.0.5.9'), IS_IPV4('10.0.5.256');
-> 1, 0
Для данного параметра, если
IS_IPV4() вернет 1,
INET_ATON() (и
INET6_ATON() )
возвратят не NULL . Обратное заявление не истина: в некоторых
случаях INET_ATON()
возвращает не NULL , когда
IS_IPV4() возвращает 0.
Как подразумевается предыдущими замечаниями,
IS_IPV4()
более строго, чем
INET_ATON()
составляет допустимый адрес IPv4, таким образом, это может быть полезно для
приложений, которые должны выполнить сильные проверки от недопустимых
значений. Альтернативно, можно использовать
INET6_ATON() ,
чтобы преобразовать IPv4 к внутренней форме и проверить на
NULL (который указывает на недопустимый адрес).
INET6_ATON()
одинаково сильно как IS_IPV4()
в проверке адресов IPv4.
IS_IPV4_COMPAT(
expr )
Эта функция берет адрес IPv6, представленный в числовой форме как двоичная
строка, как возвращено
INET6_ATON() .
Это возвращает 1, если параметр допустимый IPv4-совместимый адрес IPv6, 0
иначе. У IPv4-совместимых адресов есть форма
::ipv4_address .
mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9'));
-> 1
mysql> SELECT IS_IPV4_COMPAT(INET6_ATON('::ffff:10.0.5.9'));
-> 0
Часть IPv4 IPv4-совместимого адреса может также быть представлена,
используя шестнадцатеричную нотацию. Например, 192.168.0.1
имеет это шестнадцатеричное значение:
mysql> SELECT HEX(INET6_ATON('192.168.0.1'));
-> 'C0A80001'
Выраженный в IPv4-совместимой форме ::192.168.0.1
эквивалент ::c0a8:0001 или (без начальных нулей)
::c0a8:1 .
mysql> SELECT
-> IS_IPV4_COMPAT(INET6_ATON('::192.168.0.1')),
-> IS_IPV4_COMPAT(INET6_ATON('::c0a8:0001')),
-> IS_IPV4_COMPAT(INET6_ATON('::c0a8:1'));
-> 1, 1, 1
IS_IPV4_MAPPED(
expr )
Эта функция берет адрес IPv6, представленный в числовой форме как двоичная
строка, как возвращено
INET6_ATON() .
Это возвращает 1, если параметр допустимый IPv4-отображенный адрес IPv6, 0
иначе. У IPv4-отображенных адресов есть форма
::ffff:ipv4_address .
mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9'));
-> 0
mysql> SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.5.9'));
-> 1
Как с IS_IPV4_COMPAT() часть IPv4 IPv4-отображенного адреса
может также быть представлена, используя шестнадцатеричную нотацию:
mysql> SELECT
-> IS_IPV4_MAPPED(INET6_ATON('::ffff:192.168.0.1')),
-> IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:0001')),
-> IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:1'));
-> 1, 1, 1
IS_IPV6(expr
)
Возвращает 1, если параметр допустимый адрес IPv6, определенный как
строка, 0 иначе. Эта функция не полагает, что адреса IPv4
допустимые адреса IPv6.
mysql> SELECT IS_IPV6('10.0.5.9'), IS_IPV6('::1');
-> 0, 1
Для данного параметра если
IS_IPV6() вернет 1,
INET6_ATON()
вернет не NULL .
IS_USED_LOCK(str
)
Проверяет, используется ли блокировка str (то есть,
заблокирована). Если так, это возвращает идентификатор соединения сеанса
клиента, который держит блокировку. Иначе это возвращает NULL .
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
установлена в STATEMENT .
IS_UUID(string_uuid
)
Возвращает 1, если параметр допустимый строковый формат UUID, 0, если
параметр не допустимый UUID, и NULL ,
если параметр NULL .
Допустимый означает, что значение находится в формате,
который может быть разобран. Таким образом, это имеет правильную длину и
содержит только разрешенные символы (шестнадцатеричные цифры в любом
регистре и, произвольно, тире и скобки).
Этот формат наиболее распространен:
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
Эти форматы также разрешены:
aaaaaaaabbbbccccddddeeeeeeeeeeee
{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}
Для значений полей в пределах значения см. функциональное описание
UUID() .
mysql> SELECT IS_UUID('6ccd780c-baba-1026-9564-0040f4311e29');
+-------------------------------------------------+
| IS_UUID('6ccd780c-baba-1026-9564-0040f4311e29') |
+-------------------------------------------------+
| 1 |
+-------------------------------------------------+
mysql> SELECT IS_UUID('6CCD780C-BABA-1026-9564-0040F4311E29');
+-------------------------------------------------+
| IS_UUID('6CCD780C-BABA-1026-9564-0040F4311E29') |
+-------------------------------------------------+
| 1 |
+-------------------------------------------------+
mysql> SELECT IS_UUID('6ccd780cbaba102695640040f4311e29');
+---------------------------------------------+
| IS_UUID('6ccd780cbaba102695640040f4311e29') |
+---------------------------------------------+
| 1 |
+---------------------------------------------+
mysql> SELECT IS_UUID('{6ccd780c-baba-1026-9564-0040f4311e29}');
+---------------------------------------------------+
| IS_UUID('{6ccd780c-baba-1026-9564-0040f4311e29}') |
+---------------------------------------------------+
| 1 |
+---------------------------------------------------+
mysql> SELECT IS_UUID('6ccd780c-baba-1026-9564-0040f4311e2');
+------------------------------------------------+
| IS_UUID('6ccd780c-baba-1026-9564-0040f4311e2') |
+------------------------------------------------+
| 0 |
+------------------------------------------------+
mysql> SELECT IS_UUID(RAND());
+-----------------+
| IS_UUID(RAND()) |
+-----------------+
| 0 |
+-----------------+
MASTER_POS_WAIT(
log_name ,log_pos [,timeout
][,channel_name ])
Эта функция полезна для управления синхронизацией основной/ведомый.
Это блокирует, пока ведомое устройство не считает и применит все обновления
до указанной позиции в основном журнале. Возвращаемое значение число событий
журнала, которые должно было ждать ведомое устройство до указанной позиции.
Функция возвращает NULL , если ведомый поток SQL не запущен,
основная информация ведомого устройства не инициализирована, параметры
неправильные или ошибка происходит. Это возвращается -1 , если
тайм-аут был превышен. Если ведомые потоки SQL стоят в то время, как
MASTER_POS_WAIT()
ждет, функция возвращает NULL . Если ведомое устройство
проходит указанную позицию, функция немедленно возвращается.
Если значение timeout определено,
MASTER_POS_WAIT()
ожидает timeout секунд. Здесь
timeout должно быть больше 0: ноль или отрицательный
timeout означает отсутствие тайм-аута.
Дополнительный параметр channel
позволяет Вам выбрать, какой канал репликации применяется в функции. См.
подробности в разделе
19.2.3.
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
находится в значении STATEMENT .
NAME_CONST(name
,value )
Возвращает данное значение. Когда используется, чтобы произвести столбец
набора результатов,
NAME_CONST() заставляет столбец иметь имя.
Параметры должны быть константами.
mysql> SELECT NAME_CONST('myname', 14);
+--------+
| myname |
+--------+
| 14 |
+--------+
Эта функция только для внутреннего пользования. Сервер использует это при
построении запросов из сохраненных программ, которые содержат ссылки на
местные переменные программы, как описано в
разделе 21.7. Вы могли бы
видеть эту функцию в выводе
mysqlbinlog.
Для Ваших приложений Вы можете получить точно тот же самый результат как
в примере при использовании простого совмещения имен:
mysql> SELECT 14 AS myname;
+--------+
| myname |
+--------+
| 14 |
+--------+
1 row in set (0.00 sec)
RELEASE_ALL_LOCKS()
Снимает все названные блокировки, проводимые текущим сеансом и возвращает
число блокировок (0, если не было ни одной).
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
в состоянии STATEMENT .
RELEASE_LOCK(str
)
Снимает все блокировки, названные str . Возвращает
1 , если блокировка была выпущена, 0 , если
блокировка не была установлена этим потоком (тогда блокировка не снята) и
NULL , если названная блокировка не существовала. Блокировка не
существует, если она никогда не получалась вызовом
GET_LOCK()
или если она была ранее снята.
Запрос DO
удобно использовать с
RELEASE_LOCK() . См. раздел 14.2.3.
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
в состоянии STATEMENT .
SLEEP(duration
)
Ждет число секунд, данное параметром duration , и
затем возвращает 0. У продолжительности может быть дробная часть. Если
параметр NULL или отрицательный,
SLEEP()
производит предупреждение, или ошибку в строгом режиме SQL.
Когда функция завершает нормально (без прерывания), это возвращает 0:
mysql> SELECT SLEEP(1000);
+-------------+
| SLEEP(1000) |
+-------------+
| 0 |
+-------------+
Когда SLEEP()
единственная вещь, вызванная запросом, который прерван, она возвращает 1, а
сам запрос не возвращает ошибки. Это истина, уничтожен ли запрос, или
произошел тайм-аут:
Этот запрос прерван, используя
KILL QUERY другого сеанса:
mysql> SELECT SLEEP(1000);
+-------------+
| SLEEP(1000) |
+-------------+
| 1 |
+-------------+
- Этот запрос прерван по тайм-ауту:
mysql> SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(1000);
+-------------+
| SLEEP(1000) |
+-------------+
| 1 |
+-------------+
Когда SLEEP()
только часть запроса, который прерван, этот запрос возвращает ошибку:
Этот запрос прерван, используя
KILL QUERY другого сеанса:
mysql> SELECT 1 FROM t1 WHERE SLEEP(1000);
ERROR 1317 (70100): Query execution was interrupted
- Этот запрос прерван по тайм-ауту:
mysql> SELECT /*+ MAX_EXECUTION_TIME(1000) */ 1 FROM t1 WHERE SLEEP(1000);
ERROR 3024 (HY000): Query execution was interrupted, maximum statement
execution time exceeded
Эта функция опасна для основанной на запросе репликации. Предупреждение
зарегистрировано, если Вы используете эту функцию, когда
binlog_format
в состоянии STATEMENT .
UUID()
Возвращает универсальный уникальный идентификатор (UUID), произведенный
согласно RFC 4122, A Universally Unique IDentifier (UUID) URN Namespace
(
http://www.ietf.org/rfc/rfc4122.txt).
UUID разработан как число, которое глобально уникально в пространстве и
времени. Два вызова UUID()
произведут два различных значения, даже если эти требования будут выполнены
на двух отдельных устройствах, не соединенных друг с другом.
Хотя значения UUID()
предназначены, чтобы быть уникальными, они являются не обязательно
непредсказуемыми. Если непредсказуемость требуется, значения UUID должны быть
произведены другим путем.
UUID() возвращает
значение, которое соответствует версии 1 UUID как описано в RFC 4122.
Значение 128-битное число, представленное как строка utf8 из
пяти шестнадцатеричных чисел в формате
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee :
Первые три числа произведены из нижней, средней и верхней частей
timestamp. Верхняя часть также включает номер версии UUID.
- Четвертое число сохраняет временную уникальность в случае, если значение
timestamp теряет монотонность (например, из-за летнего времени).
- Пятое число номер узла в IEEE 802, который обеспечивает пространственную
уникальность. Случайным числом заменяют, если значение не доступно (например,
потому что у устройства узла нет никакой карты Ethernet, или неизвестно, как
найти адрес аппаратных средств интерфейса в операционной системе узла).
В этом случае, пространственная уникальность не может быть гарантирована.
Однако, у столкновения должна быть
очень низкая вероятность.
MAC-адрес интерфейса принят во внимание только в FreeBSD и Linux. В других
операционных системах MySQL использует беспорядочно
произведенное 48-битное число.
mysql> SELECT UUID();
-> '6ccd780c-baba-1026-9564-0040f4311e29'
Чтобы преобразовать между строкой и двоичным значением UUID, используйте
функции UUID_TO_BIN()
и BIN_TO_UUID()
. Чтобы проверить, является ли строка допустимым значением UUID,
используйте функцию IS_UUID()
.
UUID()
не работает с основанной на запросах репликацией.
UUID_SHORT()
Возвращает короткий универсальный идентификатор как 64-битное
целое число без знака. Значения, возвращенные
UUID_SHORT()
отличаются от строкового формата 128-битных идентификаторов, возвращенных
функцией UUID()
и имеют различные свойства уникальности. Значение
UUID_SHORT()
как гарантируют, будет уникально, если следующие условия будут выполнены:
Возвращаемое значение
UUID_SHORT() создано этим путем:
(server_id & 255) << 56
+ (server_startup_time_in_seconds << 24)
+ incremented_variable++;
mysql> SELECT UUID_SHORT();
-> 92395783831158784
UUID_SHORT()
не работает с основанной на запросе репликацией.
UUID_TO_BIN(
string_uuid ) ,
UUID_TO_BIN(
string_uuid , swap_flag )
Преобразовывает строку UUID в двоичный UUID и возвращает результат.
Описание IS_UUID()
перечисляет разрешенные строковые форматы UUID. Возвращаемое значение UUID
имеет тип VARBINARY(16) .
Если параметр UUID NULL , возвращаемое значение NULL .
Если какой-либо параметр недопустим, происходит ошибка.
UUID_TO_BIN()
берет один или два параметра:
Свопинг части времени принимает использование значений версии 1 UUID, тех,
которые произведены UUID() .
Для значений UUID, произведенных другими средствами, которые не следуют
формату версии 1, свопинг части времени не обеспечивает выгоды. Для деталей о
формате см. функциональное описание
UUID() .
Предположите, что у Вас есть следующая строка значение UUID:
mysql> SET @uuid = '6ccd780c-baba-1026-9564-0040f4311e29';
Чтобы преобразовать строку UUID в двоичный вид с или без свопинга части
времени, надо использовать
UUID_TO_BIN() :
mysql> SELECT HEX(UUID_TO_BIN(@uuid));
+----------------------------------+
| HEX(UUID_TO_BIN(@uuid)) |
+----------------------------------+
| 6CCD780CBABA102695640040F4311E29 |
+----------------------------------+
mysql> SELECT HEX(UUID_TO_BIN(@uuid, 0));
+----------------------------------+
| HEX(UUID_TO_BIN(@uuid, 0)) |
+----------------------------------+
| 6CCD780CBABA102695640040F4311E29 |
+----------------------------------+
mysql> SELECT HEX(UUID_TO_BIN(@uuid, 1));
+----------------------------------+
| HEX(UUID_TO_BIN(@uuid, 1)) |
+----------------------------------+
| 1026BABA6CCD780C95640040F4311E29 |
+----------------------------------+
Преобразовать двоичной UUID, возвращенный
UUID_TO_BIN()
в строку UUID можно через
BIN_TO_UUID() . Если Вы производите двоичный UUID, вызывая
UUID_TO_BIN()
со вторым параметром 1, чтобы поменять части времени, Вы должны также
передать второй параметр 1 в
BIN_TO_UUID()
для обратной перестановки частей времени, преобразовывая двоичной UUID
назад в строку UUID:
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid));
+--------------------------------------+
| BIN_TO_UUID(UUID_TO_BIN(@uuid))|
+--------------------------------------+
| 6ccd780c-baba-1026-9564-0040f4311e29 |
+--------------------------------------+
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0);
+--------------------------------------+
| BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0) |
+--------------------------------------+
| 6ccd780c-baba-1026-9564-0040f4311e29 |
+--------------------------------------+
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1);
+--------------------------------------+
| BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1) |
+--------------------------------------+
| 6ccd780c-baba-1026-9564-0040f4311e29 |
+--------------------------------------+
Если использование свопинга части времени не будет тем же самым для
преобразования в обоих направлениях, то оригинальный UUID не будет
восстановлен должным образом:
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),1);
+--------------------------------------+
| BIN_TO_UUID(UUID_TO_BIN(@uuid,0),1) |
+--------------------------------------+
| baba1026-780c-6ccd-9564-0040f4311e29 |
+--------------------------------------+
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),0);
+--------------------------------------+
| BIN_TO_UUID(UUID_TO_BIN(@uuid,1),0) |
+--------------------------------------+
| 1026baba-6ccd-780c-9564-0040f4311e29 |
+--------------------------------------+
VALUES(col_name
)
В запросе INSERT
... ON DUPLICATE KEY UPDATE Вы можете использовать функцию
VALUES(col_name )
в предложении UPDATE , чтобы
обратиться к значениям столбцов из
INSERT . Другими словами,
VALUES(col_name )
в UPDATE относится к значению
col_name , которое было бы вставлено,
не имея никакого конфликта дублирования ключа. Эта функция особенно полезна
при вставке многих строк. Функция
VALUES() является значащей только в предложении
ON DUPLICATE KEY UPDATE в запросе
INSERT , иначе вернет NULL . См.
раздел 14.2.5.3.
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
-> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
13.19. Агрегатные функции
(GROUP BY)
13.19.1. Обзор агрегатных функций (GROUP
BY)
Таблица 13.24. Агрегатные функции (GROUP BY )
Этот раздел описывает агрегатные (совокупные) функции, которые
воздействуют на наборы значений. Если иное не заявлено, групповые функции
игнорируют значения NULL .
Если Вы используете групповую функцию в запросе, не содержащем
GROUP BY , это эквивалентно группировке на всех строках. Для
получения дополнительной информации см.
раздел 13.19.3.
Для числовых параметров различие и функции стандартного отклонения
возвращают DOUBLE .
Функции SUM() и
AVG() возвращают значение
DECIMAL для
параметров точного значения (целое число или
DECIMAL ) и значение
DOUBLE для
для параметров приблизительной точности
(FLOAT или
DOUBLE ).
Совокупные функции SUM()
и AVG() не работают с
временными значениями. Они преобразовывают значения в числа, теряя все после
первого нечислового символа. Чтобы работать без этой проблемы, преобразуйте в
числовые модули, выполните совокупную работу, и преобразуйте назад во
временное значение. Примеры:
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col ))) FROM tbl_name ;
SELECT FROM_DAYS(SUM(TO_DAYS(date_col ))) FROM tbl_name ;
Функции вроде SUM() или
AVG() конвертируют
параметр в число в случае необходимости. Для значений
SET или
ENUM используется
основное числовое значение.
Функции BIT_AND() ,
BIT_OR() и
BIT_XOR()
выполняют битовые операции. Они требуют параметры
BIGINT (64-bit integer)
и возвращают BIGINT .
Параметры других типов преобразованы в
BIGINT
и усечение могло бы произойти.
AVG([DISTINCT]
expr )
Возвращает среднее значение expr .
Опция DISTINCT может использоваться, чтобы возвратить среднее
число отличных значений expr .
AVG() возвращает
NULL , если не было никаких строк соответствия.
mysql> SELECT student_name, AVG(test_score)
-> FROM student
-> GROUP BY student_name;
BIT_AND(expr
)
Возвращает поразрядное AND из всех битов в
expr . Вычисление выполнено с 64-битной точностью
(BIGINT ).
BIT_AND() вернет
18446744073709551615 , если не было никаких строк соответствия.
Это значение unsigned BIGINT
со всеми битами, установленными в 1.
BIT_OR(expr )
Возвращает поразрядное OR из всех битов в
expr . Вычисление выполнено с 64-битной точностью
(BIGINT ).
BIT_OR() возвращает
0 , если не было никаких строк соответствия.
BIT_XOR(expr
)
Возвращает поразрядное XOR
всех битов в expr . Вычисление выполнено с
64-битной точностью
(BIGINT ).
BIT_XOR() возвращает
0 , если не было никаких строк соответствия.
COUNT(expr )
Возвращает количество не-NULL значений
expr в строках, полученных
SELECT . Результат значение типа
BIGINT .
COUNT() возвращает
0 , если не было никаких строк соответствия.
mysql> SELECT student.student_name,COUNT(*)
-> FROM student,course
-> WHERE student.student_id=course.student_id GROUP BY student_name;
COUNT(*)
несколько отличается в том, что это возвращает количество полученных строк,
не учитывая, содержат ли они значения NULL .
COUNT(*)
оптимизирована, чтобы возвратить очень быстро, если
SELECT
получает данные от одной таблицы, никакие другие столбцы не получены и нет
предложения WHERE . Например:
mysql> SELECT COUNT(*) FROM student;
Эта оптимизация применяется только к таблицам MyISAM , потому
что точное количество строк сохранено для этого механизма хранения и может
быть получено очень быстро. Для транзакционных механизмов хранения, таких как
InnoDB , хранение точного количества строк более проблематично,
потому что многократные транзакции могут происходить, каждая из которых может
затронуть это количество.
COUNT(DISTINCT
expr ,[expr ...])
Возвращает количество строк с различными значениями не-NULL
expr .
COUNT(DISTINCT)
возвращает 0 , если не было никаких строк соответствия.
mysql> SELECT COUNT(DISTINCT results) FROM student;
В MySQL Вы можете получить число отличных комбинаций выражения, которые не
содержат NULL , давая список выражений. В стандартном SQL Вы
должны были бы сделать связь всех выражений внутри
COUNT(DISTINCT ...) .
GROUP_CONCAT(expr
)
Эта функция возвращает строковый результат со связанными
не-NULL значениями из группы. Это возвращает NULL ,
если значений не-NULL нет. Полный синтаксис следующий:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr }
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val ])
mysql> SELECT student_name, GROUP_CONCAT(test_score)
-> FROM student
-> GROUP BY student_name;
Или:
mysql> SELECT student_name, GROUP_CONCAT(DISTINCT test_score
-> ORDER BY test_score DESC SEPARATOR ' ')
-> FROM student GROUP BY student_name;
В MySQL Вы можете получить связанные значения комбинаций выражения.
Чтобы устранить дублирующие значения, используйте
DISTINCT . Чтобы отсортировать значения в результате, используйте
ORDER BY . Чтобы отсортировать в обратном порядке, добавьте
ключевое слово DESC к названию столбца, который Вы сортируете в
ORDER BY . Значение по умолчанию порядок по возрастанию, это
может быть определено явно, используя ключевое слово ASC .
Разделитель по умолчанию между значениями в группе запятая
(, ). Чтобы определить разделитель явно, надо использовать
SEPARATOR сопровождаемое строковым значением, которое должно
быть вставлено между групповыми значениями. Чтобы устранить разделитель
вообще, определите SEPARATOR '' .
Результат является усеченным к максимальной длине, которая дана переменной
group_concat_max_len
, у которой есть значение по умолчанию 1024. Значение может быть
установлено выше, хотя эффективная максимальная длина возвращаемого значения
ограничена значением
max_allowed_packet
. Синтаксис, чтобы изменить значение
group_concat_max_len
во время выполнения, где
val unsigned integer:
SET [GLOBAL | SESSION] group_concat_max_len = val ;
Возвращаемое значение недвоичная или двоичная строка, в зависимости от
того, являются ли параметрами недвоичные или двоичные строки. Тип результата
TEXT или
BLOB . Если
group_concat_max_len
меньше или равно 512, тогда тип результата
VARCHAR или
VARBINARY .
JSON_ARRAYAGG([
col )
Соединяет набор результатов как массив
JSON , чьи элементы состоят из
строк. Порядок элементов в этом массиве неопределен. Функция действует на
столбец или выражение, которое оценивается к единственному значению.
Возвращает NULL , если результат не содержит строк,
или в случае ошибки.
Эта функция была добавлена в MySQL 8.0.1.
mysql> SELECT col FROM t1;
+--------------------------------------+
| col |
+--------------------------------------+
| {"key1": "value1", "key2": "value2"} |
| {"keyA": "valueA", "keyB": "valueB"} |
+--------------------------------------+
2 rows in set (0.00 sec)
mysql> SELECT JSON_ARRAYAGG(col) FROM t1;
+------------------------------------------------------------------------------+
| JSON_ARRAYAGG(col) |
+------------------------------------------------------------------------------+
| [{"key1": "value1", "key2": "value2"}, {"keyA": "valueA", "keyB": "valueB"}] |
+------------------------------------------------------------------------------+
1 row in set (0.00 sec)
JSON_OBJECTAGG([
key , value )
Берет два имени столбцов или выражения как параметры, первый из них
используется в качестве ключа, второй как значение, и возвращает объект JSON,
содержащий пары ключа/значения. Элементы с дубликатами ключей пропущены.
Вы можете определить константу как ключ, но результат всегда содержит самое
большее один элемент строки. Возвращает NULL , если результат не
содержит строк, или в случае ошибки. Ошибка происходит, если какое-либо
ключевое имя NULL или число параметров не равно 2.
Эта функция была добавлена в MySQL 8.0.1.
mysql> SELECT id, name FROM t3 WHERE id < 10;
+----+------+
| id | name |
+----+------+
|2 | joe |
|5 | fred |
+----+------+
2 rows in set (0.00 sec)
mysql> SELECT JSON_OBJECTAGG(id, name) FROM t3 WHERE id < 10;
+---------------------------+
| JSON_OBJECTAGG(id, name) |
+---------------------------+
| {"2": "joe", "5": "fred"} |
+---------------------------+
1 row in set (0.00 sec)
MAX([DISTINCT]
expr )
Возвращает максимальное значение expr .
MAX()
может взять строковый параметр, в таких случаях это возвращает максимальное
строковое значение. См. раздел 9.3.1.
Ключевое слово DISTINCT
может использоваться, чтобы найти максимум отличных значений
expr , однако, это приводит к тому же самому результату,
как и исключение DISTINCT .
MAX() возвращает
NULL , если не было никаких строк соответствия.
mysql> SELECT student_name, MIN(test_score), MAX(test_score)
-> FROM student
-> GROUP BY student_name;
Для MAX() MySQL
в настоящее время сравнивает столбцы ENUM
и SET
их строковым значением, а не относительной позицией строки в наборе. Это
отличается от сравнения ORDER BY .
Это, как ожидают, будет исправлено в будущем выпуске MySQL.
MIN([DISTINCT]
expr )
Возвращает минимальное значение expr .
MIN()
может взять строковый параметр, в таких случаях это возвращает минимальное
строковое значение. См. раздел 9.3.1.
Ключевое слово DISTINCT
может использоваться, чтобы найти минимум отличных значений
expr , однако, это приводит к тому же самому результату,
как и исключение DISTINCT .
MIN() возвращает
NULL , если не было никаких строк соответствия.
mysql> SELECT student_name, MIN(test_score), MAX(test_score)
-> FROM student
-> GROUP BY student_name;
Для MIN() MySQL
в настоящее время сравнивает столбцы ENUM
и SET
их строковым значением, а не относительной позицией строки в наборе. Это
отличается от сравнения ORDER BY .
Это, как ожидают, будет исправлено в будущем выпуске MySQL.
STD(expr )
Возвращает стандартное отклонение expr .
Это расширение к стандартному SQL. Стандартная функция SQL
STDDEV_POP()
может использоваться вместо этого.
STD()
возвращает NULL , если не было никаких строк соответствия.
STDDEV(expr )
Возвращает стандартное отклонение expr .
Эта функция обеспечена для совместимости с Oracle.
Стандартная функция SQL
STDDEV_POP() может использоваться вместо этого.
STDDEV()
возвращает NULL , если не было никаких строк соответствия.
STDDEV_POP(expr
)
Возвращает стандартное отклонение expr
(квадратный корень VAR_POP()
). Вы можете также использовать
STD() или
STDDEV() ,
которые эквивалентны, но не стандартный SQL.
STDDEV_POP()
возвращает NULL , если не было никаких строк соответствия.
STDDEV_SAMP(expr
)
Возвращает типовое стандартное отклонение expr
(квадратный корень VAR_SAMP()
).
STDDEV_SAMP()
возвращает NULL , если не было никаких строк соответствия.
SUM([DISTINCT]
expr )
Возвращает сумму expr . Если у набора
нет никаких строк, SUM()
возвращает NULL . Ключевое слово DISTINCT может
использоваться, чтобы суммировать только
отличные значения expr .
SUM()
возвращает NULL , если не было никаких строк соответствия.
VAR_POP(expr
)
Возвращает различие стандарта expr .
Это рассматривает строки как целое, не как образец, таким образом, у этого
есть число строк как знаменатель. Вы можете также использовать
VARIANCE() ,
который эквивалентен, но не является стандартом SQL.
VAR_POP()
возвращает NULL , если не было никаких строк соответствия.
VAR_SAMP(expr
)
Возвращает типовое различие expr . Таким образом,
знаменатель число строк минус одна.
VAR_SAMP()
возвращает NULL , если не было никаких строк соответствия.
VARIANCE(expr
)
Возвращает различие стандарта expr .
Это расширение к стандартному SQL. Стандартная функция SQL
VAR_POP()
может использоваться вместо этого.
VARIANCE()
возвращает NULL , если не было никаких строк соответствия.
13.19.2. Модификаторы GROUP BY
Предложение GROUP BY разрешает модификатор WITH
ROLLUP , который заставляет добавить дополнительные строки
к итоговому выводу. Эти строки представляют более высокий уровень (или
суперсовокупность). ROLLUP позволяет Вам ответить на вопросы
на многих уровнях анализа единственным запросом. Это может использоваться,
например, чтобы оказать поддержку для OLAP (Online Analytical Processing).
Предположите, что таблица названа sales и имеет столбцы
year , country , product и
profit для того, чтобы сделать запись доходности продаж:
CREATE TABLE sales (yearINT NOT NULL,
country VARCHAR(20) NOT NULL,
product VARCHAR(32) NOT NULL, profit INT);
Содержание таблицы может быть получено в итоге ежегодно с простым
GROUP BY так:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
+------+-------------+
Этот вывод показывает полную прибыль в течение каждого года, но если Вы
также хотите определить полную прибыль, суммированную за все годы, Вы должны
сложить отдельные значения самостоятельно или выполнить дополнительный запрос.
Или Вы можете использовать ROLLUP , который обеспечивает оба
уровня анализа с единственным запросом. Добавление модификатора WITH
ROLLUP к GROUP BY заставляет запрос производить
другую строку, которая показывает общий итог по всем значениям года:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
| NULL | 7535 |
+------+-------------+
Итоговая строка суперсовокупности идентифицирована значением
NULL в столбце year .
ROLLUP имеет более сложный эффект, когда там многократные
столбцы в GROUP BY . В этом случае каждый раз есть
изменение в значении в любом, но обязательно последнем столбце группировки,
а запрос производит дополнительную суперсовокупную сводную строку.
Например, без ROLLUP резюме для таблицы sales ,
основанное на year , country и product
могло бы быть похожим на это:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales GROUP BY year, country, product;
+------+---------+------------+-------------+
| year | country | product | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer | 1500 |
| 2000 | Finland | Phone | 100 |
| 2000 | India | Calculator | 150 |
| 2000 | India | Computer | 1200 |
| 2000 | USA | Calculator | 75 |
| 2000 | USA | Computer | 1500 |
| 2001 | Finland | Phone | 10 |
| 2001 | USA | Calculator | 50 |
| 2001 | USA | Computer | 2700 |
| 2001 | USA | TV | 250 |
+------+---------+------------+-------------+
Вывод указывает, что резюме оценивает только на уровне
year/country/product анализа. Когда ROLLUP добавлен, запрос
производит несколько дополнительных строк:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales GROUP BY year, country, product WITH ROLLUP;
+------+---------+------------+-------------+
| year | country | product | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer | 1500 |
| 2000 | Finland | Phone | 100 |
| 2000 | Finland | NULL | 1600 |
| 2000 | India | Calculator | 150 |
| 2000 | India | Computer | 1200 |
| 2000 | India | NULL | 1350 |
| 2000 | USA | Calculator | 75 |
| 2000 | USA | Computer | 1500 |
| 2000 | USA | NULL | 1575 |
| 2000 | NULL | NULL | 4525 |
| 2001 | Finland | Phone | 10 |
| 2001 | Finland | NULL | 10 |
| 2001 | USA | Calculator | 50 |
| 2001 | USA | Computer | 2700 |
| 2001 | USA | TV | 250 |
| 2001 | USA | NULL | 3000 |
| 2001 | NULL | NULL | 3010 |
| NULL | NULL | NULL | 7535 |
+------+---------+------------+-------------+
Для этого запроса добавление ROLLUP заставляет вывод включить
итоговую информацию по четырем уровням анализа, а не только одному. Вот как
интерпретировать вывод ROLLUP :
Другие соображения, используя ROLLUP
Следующие элементы перечисляют некоторые особенности поведения,
определенные для выполнения MySQL ROLLUP .
Когда Вы используете ROLLUP , Вы не можете также использовать
ORDER BY , чтобы сортировать результаты. Другими словами,
ROLLUP и ORDER BY являются взаимоисключающими.
Однако, Вы все еще имеете некоторый контроль над порядком сортировки.
GROUP BY в MySQL неявно сортирует результаты, и Вы можете
использовать явные ключевые слова ASC и DESC
со столбцами, названными в списке GROUP BY , чтобы определить
порядок сортировки для отдельных столбцов. Высокоуровневые сводные строки,
добавленные ROLLUP все еще появятся
после строк, от которых они вычислены, независимо от порядка сортировки.
Неявная сортировка GROUP BY в MySQL 8.0 устарела.
Чтобы достигнуть определенного порядка сортировки сгруппированных
результатов, предпочтительно использовать явное предложение
ORDER BY . Это можно обойти помещая ROLLUP
в пределах подзапроса. Например:
mysql> SELECT * FROM (SELECT year, country, SUM(profit) FROM sales
-> GROUP BY year WITH ROLLUP) derived_t1 ORDER BY year;
LIMIT может использоваться, чтобы ограничить число строк,
возвращенных клиенту. LIMIT применен после ROLLUP ,
таким образом, предел применяется против дополнительных строк,
добавленных ROLLUP . Например:
mysql> SELECT year, country, product, SUM(profit)
-> FROM sales GROUP BY year, country, product WITH ROLLUP
-> LIMIT 5;
+------+---------+------------+-------------+
| year | country | product | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer | 1500 |
| 2000 | Finland | Phone | 100 |
| 2000 | Finland | NULL | 1600 |
| 2000 | India | Calculator | 150 |
| 2000 | India | Computer | 1200 |
+------+---------+------------+-------------+
Использование LIMIT с ROLLUP
может привести к результатам, которые трудно интерпретировать, потому что у
Вас есть меньше контекста для того, чтобы понять суперсовокупные строки.
NULL в каждой суперсовокупной строке произведен, когда строку
посылают клиенту. Сервер смотрит на столбцы, названные в GROUP BY
после крайнего левого, который изменил значение. Для любого столбца в
наборе результатов с именем, которое соответствует любому из тех имен, его
значение установлено в NULL . Если Вы определяете
группирующиеся столбцы номером столбца, сервер идентифицирует который столбец
установить в NULL по номеру.
Поскольку значения NULL в суперсовокупных строках помещены в
набор результатов в такой позднец стадии в обработке запроса, Вы не можете
проверить их как значения NULL
в пределах запроса непосредственно. Например, Вы не можете добавить
HAVING product IS NULL к запросу, чтобы устранить из вывода все,
кроме суперсовокупных строк.
С другой стороны, значения NULL действительно появляются как
NULL на стороне клиента и могут быть проверены с использованием
любого клиента MySQL.
MySQL разрешает столбец, который не появляется в списке GROUP BY
и назван в списке select. В этом случае сервер свободен выбрать любое
значение из этого несоединенного столбца в сводных строках, и это включает
дополнительные строки, добавленные WITH ROLLUP .
Например, в следующем запросе country
несоединенный столбец, который не появляется в списке GROUP BY
и значения, выбранные для этого столбца, неопределенны:
mysql> SELECT year, country, SUM(profit)
-> FROM sales GROUP BY year WITH ROLLUP;
+------+---------+-------------+
| year | country | SUM(profit) |
+------+---------+-------------+
| 2000 | India | 4525 |
| 2001 | USA | 3010 |
| NULL | USA | 7535 |
+------+---------+-------------+
Это поведение происходит, если режим SQL
ONLY_FULL_GROUP_BY
выключен. Иначе сервер отклоняет запрос как незаконный потому,
что country не перечислен в предложении GROUP BY .
Для получения дополнительной информации о несоединенных столбцах и
GROUP BY см. раздел
13.19.3.
13.19.3. Обработка MySQL GROUP BY
SQL92 и ранее не разрешает запросы для которых список select с выражением
HAVING или списком ORDER BY
обращается к несоединенным столбцам, которые не называются в
GROUP BY или функционально зависят от (уникально определены)
столбцов GROUP BY . Например, этот запрос незаконен в стандартном
SQL92 потому что несоединенный столбец name в списке select не
появляется в GROUP BY :
SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid GROUP BY o.custid;
Чтобы запрос был законным в SQL92, столбец name должен быть
исключен из списка select или назван в GROUP BY .
SQL99 и позже разрешает такие несовокупности, если они функционально
зависят от столбцов GROUP BY : если такие отношения существуют
между name и custid , запрос является законным. Это
имело бы место, например, если custid
первичный ключ customers .
MySQL осуществляет обнаружение функциональной зависимости. Если режим SQL
ONLY_FULL_GROUP_BY
включен (это так по умолчанию), MySQL отклоняет запросы, для
который список select, выражение HAVING или список
ORDER BY обращаются к несоединенным столбцам, которые не
называют в GROUP BY и функционально не зависят от
столбцов в GROUP BY .
Если
ONLY_FULL_GROUP_BY выключен, расширение MySQL к стандартному
использованию SQL GROUP BY разрешает такие запросы.
Это заставляет MySQL принимать предыдущий запрос. В этом случае сервер
свободен выбрать любое значение из каждой группы, так что, если они не то же
самое, выбранные значения не определены. Кроме того, выбор значений из каждой
группы не может быть под влиянием ORDER BY .
Сортировка набора результатов происходит после того, как значения были
выбраны, и ORDER BY не затрагивает, какое значение в пределах
каждой группы сервер выбирает. Отключение
ONLY_FULL_GROUP_BY
полезно прежде всего, когда Вы знаете что, из-за некоторого
свойства данных, все значения в каждом несоединенном столбце, не названном в
GROUP BY те же самые для каждой группы.
Вы можете достигнуть того же самого эффекта без отключения
ONLY_FULL_GROUP_BY
, используя
ANY_VALUE() и обратиться к несоединенному столбцу.
Следующее обсуждение демонстрирует функциональную зависимость, сообщение
об ошибке, которое производит MySQL, когда функциональная зависимость
отсутствует, и способы заставить MySQL принимать запрос в
отсутствие функциональной зависимости.
Этот запрос мог бы быть недопустимым с включенным
ONLY_FULL_GROUP_BY
, потому что несоединенный столбец address в списке
select не называют в GROUP BY :
SELECT name, address, MAX(age) FROM t GROUP BY name;
Запрос допустим, если name первичный ключ t или
уникальный столбец NOT NULL . В таких случаях MySQL признает, что
выбранный столбец функционально зависит от группирующего столбца. Например,
если name первичный ключ, его значение определяет значение
address потому что у каждой группы есть только одно значение
первичного ключа и таким образом только одна строка. В результате нет никакой
хаотичности в выборе значения address
в группе и никакой потребности отклонить запрос.
Запрос недопустим, если name не первичный ключ t
или уникальный столбец NOT NULL . В этом случае никакая
функциональная зависимость не может быть выведена, и ошибка происходит:
mysql> SELECT name, address, MAX(age) FROM t GROUP BY name;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP
BY clause and contains nonaggregated column 'mydb.t.address' which
is not functionally dependent on columns in GROUP BY clause; this
is incompatible with sql_mode=only_full_group_by
Если Вы знаете, что для определенных данных
каждое значение name фактически уникально определяет
address , то address эффективно функционально
зависит от name . Чтобы сказать MySQL принять запрос, Вы можете
использовать ANY_VALUE()
:
SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
Альтернативно, отключите
ONLY_FULL_GROUP_BY
.
Предыдущий пример довольно прост, как бы то ни было. В частности,
маловероятно, что Вы сгруппировались бы на единственном столбце первичного
ключа, потому что каждая группа будет содержать только одну строку.
Для примеров, демонстрирующих функциональную зависимость в более сложных
запросах см. раздел
13.19.4.
Если у запроса есть совокупные функции и нет GROUP BY , он
не может иметь несоединенные столбцы в списке select, выражении
HAVING или списке ORDER BY с включенным режимом
ONLY_FULL_GROUP_BY
:
mysql> SELECT name, MAX(age) FROM t;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
#1 of SELECT list contains nonaggregated column 'mydb.t.name'; this
is incompatible with sql_mode=only_full_group_by
Без GROUP BY есть единственная группа и неопределенно,
которое значение name выбрать для группы. Здесь также
может использоваться ANY_VALUE()
, если несущественно, которое значение
name MySQL выбирает:
SELECT ANY_VALUE(name), MAX(age) FROM t;
ONLY_FULL_GROUP_BY также влияет на обработку
DISTINCT и ORDER BY .
Рассмотрите случай таблицы t с тремя столбцами
c1 , c2 и c3 , которые
содержат эти строки:
c1 c2 c3
1 2 A
3 4 B
1 2 C
Предположите, что мы выполняем следующий запрос, ожидая, что результаты
будут упорядочены по c3 :
SELECT DISTINCT c1, c2 FROM t ORDER BY c3;
Чтобы упорядочить результат, сначала должны быть устранены дубликаты.
Но какую строку мы должны сохранить, первую или третью? Этот произвольный
выбор влияет на сохраненное значение c3 , что
в свою очередь влияет на упорядочивание и делает его произвольным. Чтобы
предотвратить эту проблему, запрос, который имеет
DISTINCT и ORDER BY отклонен как недопустимый, если
выражение ORDER BY не удовлетворяет по крайней мере одно
из этих условий:
Другое расширение MySQL к стандартному SQL разрешает ссылки в
HAVING выражениям в списке select. Например, следующий запрос
возвращает значения name , которые только
одни в таблице orders :
SELECT name, COUNT(name) FROM orders GROUP BY name HAVING COUNT(name) = 1;
Расширение MySQL разрешает использование псевдонима в
HAVING для соединенного столбца:
SELECT name, COUNT(name) AS c FROM orders GROUP BY name HAVING c = 1;
Включение
ONLY_FULL_GROUP_BY отключает это расширение, таким образом требуя
HAVING , который будет написан, используя
выражения без псевдонимов.
Стандартный SQL не разрешает выражения в GROUP BY , таким
образом, этот запрос недопустим:
SELECT id, FLOOR(value/100) FROM tbl_name
GROUP BY id, FLOOR(value/100);
MySQL расширяет стандартный SQL, чтобы разрешить выражения в
GROUP BY и считает предыдущий запрос допустимым.
Стандартный SQL также не разрешает псевдонимы в GROUP BY .
MySQL расширяет стандартный SQL, чтобы разрешить псевдонимы, таким образом,
другой способ написать запрос следующий:
SELECT id, FLOOR(value/100) AS val
FROM tbl_name
GROUP BY id, val;
13.19.4.
Обнаружение функциональной зависимости
Следующее обсуждение обеспечивает несколько примеров путей, которыми MySQL
обнаруживает функциональные зависимости. Примеры используют эту нотацию:
{X } -> {Y }
Поймите это как X уникально определяет
Y , это также означает, что
Y функционально зависит от X .
Примеры используют базу данных world , которая может быть
загружена с MySQL Documentation page. Вы можете найти детали о том, как
установить базу данных на той же самой странице.
Функциональные зависимости, полученные из ключей
Следующий запрос выбирает для каждой страны количество разговорных языков:
SELECT co.Name, COUNT(*) FROM countrylanguage cl, country co
WHERE cl.CountryCode = co.Code GROUP BY co.Code;
co.Code первичный ключ
co , так что все столбцы co
функционально зависят от этого, как выражено здесь:
{co.Code} -> {co.*}
Таким образом, co.name функционально зависит от столбцов
GROUP BY и запрос допустим.
Индекс UNIQUE по столбцу NOT NULL
мог использоваться вместо первичного ключа, и та же самая функциональная
зависимость применится. Это не истина для индекса UNIQUE ,
который разрешает значения NULL , потому что это разрешает
многократные значения NULL и в этом случае уникальность потеряна.
Функциональные зависимости, полученные из ключей нескольких
столбцов и из равенств
Этот запрос выбирает для каждой страны список всех разговорных языков и
сколько людей говорит на них:
SELECT co.Name, cl.Language,
cl.Percentage * co.Population / 100.0 AS SpokenBy
FROM countrylanguage cl, country co
WHERE cl.CountryCode = co.Code
GROUP BY cl.CountryCode, cl.Language;
Пара (cl.CountryCode , cl.Language ) задает
сложный первичный ключ на двух столбцах cl ,
так, чтобы пара столбцов уникально определила все столбцы cl :
{cl.CountryCode, cl.Language} -> {cl.*}
Кроме того, из-за равенства в WHERE :
{cl.CountryCode} -> {co.Code}
И потому что co.Code первичный ключ co :
{co.Code} -> {co.*}
Уникально определенные являются переходными, поэтому:
{cl.CountryCode, cl.Language} -> {cl.*,co.*}
В результате запрос допустим.
Как с предыдущим примером, ключ UNIQUE на столбцах
NOT NULL мог бы использоваться вместо первичного ключа.
Условие INNER JOIN может использоваться вместо
WHERE . Те же самые функциональные зависимости применяются:
SELECT co.Name, cl.Language, cl.Percentage * co.Population/100.0 AS SpokenBy
FROM countrylanguage cl INNER JOIN country co
ON cl.CountryCode = co.Code
GROUP BY cl.CountryCode, cl.Language;
Особые случаи функциональной зависимости
Принимая во внимание, что тест равенства в WHERE или
INNER JOIN симметричен, тест равенства во внешнем условии
соединения не такой, потому что таблицы играют различные роли.
Предположите, что целостность была случайно сломана и там существует
строка countrylanguage без соответствующей строки в
country . Рассмотрите тот же самый запрос как в предыдущем
примере, но с LEFT JOIN :
SELECT co.Name, cl.Language,
cl.Percentage * co.Population/100.0 AS SpokenBy
FROM countrylanguage cl LEFT JOIN country co
ON cl.CountryCode = co.Code
GROUP BY cl.CountryCode, cl.Language;
Для данного значения cl.CountryCode значение
co.Code
в соединеннном результате найден в соответствующей строке (определенной
cl.CountryCode ) или дополнен NULL , если там нет
соответствия (также определено cl.CountryCode ).
В каждом случае применяются эти отношения:
{cl.CountryCode} -> {co.Code}
cl.CountryCode самостоятельно функционально зависит от
{cl.CountryCode , cl.Language },
который является первичным ключом.
Если в результате соединения co.Code дополнен
NULL , то и co.Name тоже. Если co.Code
не дополнен NULL , это потому, что
co.Code первичный ключ, это определяет
co.Name . Поэтому во всех случаях:
{co.Code} -> {co.Name}
что уступает:
{cl.CountryCode, cl.Language} -> {cl.*,co.*}
В результате запрос допустим.
Однако, предположите, что таблицы поменяны, как в этом запросе:
SELECT co.Name, cl.Language,
cl.Percentage * co.Population/100.0 AS SpokenBy
FROM country co LEFT JOIN countrylanguage cl
ON cl.CountryCode = co.Code
GROUP BY cl.CountryCode, cl.Language;
Теперь эти отношения не применяются:
{cl.CountryCode, cl.Language} -> {cl.*,co.*}
Действительно, все NULL -дополненные строки, сделанные для
cl будут помещены в единственную группу (у них есть оба
столбца GROUP BY равные NULL ),
и в этой группе значение co.Name
может измениться. Запрос недопустим, и MySQL отклоняет его.
Функциональная зависимость во внешних соединениях, таким образом,
соединена с тем, принадлежат ли определяющие столбцы левой или правой стороне
LEFT JOIN . Определение функциональной зависимости становится
более сложным, если там вложены внешние соединения или условие соединения не
состоит полностью из сравнений равенства.
Функциональные зависимости и представления
Предположите, что представление о странах производит их код, их имя в
верхнем регистре, и сколько различных официальных языков они имеют:
CREATE VIEW Country2 AS
SELECT co.Code, UPPER(co.Name) AS UpperName,
COUNT(cl.Language) AS OfficialLanguages
FROM country AS co JOIN countrylanguage AS cl
ON cl.CountryCode = co.Code WHERE cl.isOfficial = 'T'
GROUP BY co.Code;
Это определение допустимо потому, что:
{co.Code} -> {co.*}
В результате представления первый выбранный столбец
co.Code , который является также групповым столбцом и таким
образом определяет все другие выбранные выражения:
{Country2.Code} -> {Country2.*}
MySQL понимает это и использует эту информацию, как описано после.
Этот запрос выводит на экран страны, сколько различных официальных языков
они имеют, и сколько городов они имеют, присоединяясь к
представлению с таблицей city :
SELECT co2.Code, co2.UpperName, co2.OfficialLanguages,
COUNT(*) AS Cities FROM country2 AS co2 JOIN city ci
ON ci.CountryCode = co2.Code GROUP BY co2.Code;
Этот запрос допустим потому что, как замечено ранее:
{co2.Code} -> {co2.*}
MySQL в состоянии обнаружить функциональную зависимость в результате
представления и применить ее, чтобы утвердить запрос, который использует
представление. То же самое было бы истиной, если country2
была созданной таблицей, как в:
SELECT co2.Code, co2.UpperName, co2.OfficialLanguages, COUNT(*) AS Cities
FROM (SELECT co.Code, UPPER(co.Name) AS UpperName,
COUNT(cl.Language) AS OfficialLanguages
FROM country AS co JOIN countrylanguage AS cl
ON cl.CountryCode=co.Code WHERE cl.isOfficial='T'
GROUP BY co.Code)
AS co2 JOIN city ci ON ci.CountryCode = co2.Code GROUP BY co2.Code;
Комбинации функциональных зависимостей
MySQL в состоянии объединить все предыдущие типы функциональных
зависимостей, чтобы утвердить более сложные запросы.
13.20. Точная математика
MySQL оказывает поддержку для точной математики: числовое значение,
которое приводит к чрезвычайно точным результатам, и управление недопустимыми
значениями. Математика точности основана на этих двух особенностях:
Эти особенности имеют несколько значений для числовых операций и
обеспечивают высокую степень согласия со стандартным SQL:
Точные вычисления:
Для чисел точного значения вычисления не вводят ошибки с плавающей запятой.
Вместо этого используется высокая точность. Например, MySQL обрабатывает
такое число, как .0001 как точное значение, а не как
приближение, и суммирование его 10000 раз приводит к результату точно
1 , а не значению, которое
является просто близким к 1.
- Четкое поведение округления:
Для чисел точного значения результат
ROUND()
зависит от параметра, а не от таких факторов окружающей среды,
как основная библиотека C.
- Независимость от платформы:
Операции на точных числовых значениях те же самое на различных платформах,
таких как Windows и Unix.
- Управление обработкой недопустимых значений
: Переполнение и деление на ноль обнаруживаемы и могут быть обработаны
как ошибки. Например, Вы можете обработать значение, которое является слишком
большим для столбца, как ошибку вместо того, чтобы иметь значение, усеченное
до пределов диапазона типа данных столбца. Точно так же Вы можете обработать
деление на ноль как ошибку, а не как работу, которая приводит к результату
NULL . Многое определено установкой режима SQL сервера.
Следующее обсуждение покрывает несколько аспектов того, как математика
точности работает, включая возможные несовместимости с более старыми
приложениями. В конце некоторые примеры демонстрируют, как MySQL обрабатывает
числовые операции точно. Для информации об управлении режимом SQL см.
раздел 6.1.8.
13.20.1. Типы числовых значений
Контекст математики точности для операций точного значения включает типы
данных точного значения (целое число и
DECIMAL )
и точное значение числовых литералов. Типы данных приблизительной точности и
числовые литералы обработаны как числа с плавающей запятой.
У точного значения числовых литералов есть часть целого числа или дробная
часть, или обе. Они могут быть со знаком. Примеры: 1 ,
.2 , 3.4 , -5 , -6.78 ,
+9.10 .
Числа приблизительной точности представлены в экспоненциальном
представлении с мантиссой и экспонентой. Обе части могут быть
со знаком. Примеры: 1.2E3 , 1.2E-3 ,
-1.2E3 , -1.2E-3 .
Два числа, которые выглядят подобными, могут быть обработаны по-другому.
Например, 2.34 точное значение (фиксированная точка), тогда как
2.34E0 приблизительное число (с плавающей запятой).
Тип данных DECIMAL
тип с фиксированной точкой, вычисления точны. В MySQL тип
у типа DECIMAL
есть несколько синонимов:
NUMERIC ,
DEC ,
FIXED . Типы целого
числа это типы точного значения.
Типы FLOAT и
DOUBLE
типы с плавающей запятой, вычисления приблизительны. В MySQL типы, которые
синонимичны с
FLOAT или
DOUBLE это
DOUBLE PRECISION и
REAL .
13.20.2.
Характеристики типа данных DECIMAL
Этот раздел обсуждает характеристики типа данных
DECIMAL
(и его синонимов) с особым отношением к следующим темам:
Синтаксис декларации для столбцов
DECIMAL
DECIMAL(M ,D ) .
Диапазоны значений для параметров следующие:
Максимальное значение 65 для M означает, что
вычисления на значениях DECIMAL
точны до 65 цифр. Этот предел точности в 65 цифр также относится
к точному значению числовых литералов, таким образом, максимальный диапазон
таких литералов отличается.
Значения для столбцов DECIMAL
сохранены, используя двоичный формат, который упаковывает девять
десятичных цифр в 4 байта. Требования хранения для целого числа и дробных
частей каждого значения определены отдельно. Каждое число, кратное девяти
цифрам, требует 4 байтов, и любые остающиеся перенесенные цифры требуют
некоторой части 4 байтов. Хранение, требуемое для оставшихся цифр,
дано следующей таблицей.
Оставшиеся цифры |
Число байтов |
0 | 0 |
1-2 | 1 |
3-4 | 2 |
5-6 | 3 |
7-9 | 4 |
Например, у столбца DECIMAL(18,9)
есть девять цифр по обе стороны от десятичной запятой, таким образом, часть
целого числа и дробная часть требуют по 4 байта. Столбец
DECIMAL(20,6) имеет четырнадцать цифр целого числа и шесть
дробных цифр. Цифры целого числа требуют четырех байтов для девяти цифр и 3
байтов для оставшихся пяти. Шесть дробных цифр требуют еще 3 байтов.
Столбцы DECIMAL
не хранят символы + или - , также старотовые нули.
Если Вы вставляете +0003.1 в столбец типа DECIMAL(5,1)
, это сохранено как 3.1 . Для отрицательных чисел
символ - не сохранен.
Столбцы DECIMAL
не разрешают значения, больше чем диапазон, подразумеваемый определением
столбца. Например, столбец DECIMAL(3,0)
поддерживает диапазон от -999 до 999 . Столбец
DECIMAL(M , D )
разрешает самое большее M -D
цифр слева от десятичной запятой.
Стандарт SQL требует, чтобы точность
NUMERIC(M ,D )
была точно M цифр. Для
DECIMAL(M ,D )
стандарт требует точности, по крайней мере, M
цифр, но разрешает и больше. В MySQL
DECIMAL(M ,D ) и
NUMERIC(M ,D )
то же самое, и у обоих есть точность строго M цифр.
Для полного объяснения внутреннего формата значения
DECIMAL см. файл
strings/decimal.c в исходных текстах MySQL.
Формат объяснен (с примером) в функции decimal2bin() .
13.20.3. Обработка выражений
С математикой числа точного значения используются как дано, когда это
возможно. Например, числа в сравнениях используются точно как даны без
изменения в значении. В строгом режиме SQL для
INSERT в столбец с точным типом
данных (DECIMAL или
integer), число вставлено с его точным значением, если это в пределах
диапазона столбца. Когда получено, значение должно быть тем же самым как то,
что было вставлено. Если строгий режим SQL не включен, усечение для
INSERT допустимо.
Обработка числового выражения зависит от того, какие
значения выражение содержит:
Если числовое выражение содержит какие-либо строки, они преобразованы в
двоичную точность, значения с плавающей запятой и выражение приблизительны.
Вставки в числовые столбцы, затронуты режимом SQL, которым управляет
системная переменная sql_mode
. См. раздел 6.1.8.
Следующее обсуждение упоминает строгий режим (выбранный значениями режима
STRICT_ALL_TABLES
или
STRICT_TRANS_TABLES ) и
ERROR_FOR_DIVISION_BY_ZERO .
Чтобы включить все ограничения, Вы можете просто использовать режим
TRADITIONAL ,
который включает строгие значения режима и
ERROR_FOR_DIVISION_BY_ZERO :
mysql> SET sql_mode='TRADITIONAL';
Если число вставлено в столбец точного типа
(DECIMAL или integer),
оно вставлено с его точным значением, если это в пределах диапазона столбца.
Если у значения есть слишком много цифр в дробной части, округление
происходит, и предупреждение произведено. Округление сделано как описано в
разделе 13.20.4.
Если у значения есть слишком много цифр в части целого числа, оно является
слишком большим и обработано следующим образом:
Для вставок строк в числовые столбцы преобразование строки в число
обработано следующим образом, если у строки есть нечисловое содержание:
По умолчанию деление на ноль приводит к результату NULL и
ни к какому предупреждению. Устанавливая режим SQL соответственно,
деление на ноль может быть ограничено.
В режиме SQL
ERROR_FOR_DIVISION_BY_ZERO
MySQL обрабатывает деление на ноль по-другому:
Другими словами, вставки и обновления, вовлекающие выражения, которые
вызывают деление на ноль могут быть обработаны как ошибки, но это требует
ERROR_FOR_DIVISION_BY_ZERO в дополнение к строгому режиму.
Предположите, что у нас есть этот запрос:
INSERT INTO t SET i = 1/0;
Это то, что происходит для комбинации строгого режима и
ERROR_FOR_DIVISION_BY_ZERO .
Значение
sql_mode | Результат |
'' (Значение по умолчанию) |
Никакого предупреждения, никакой ошибки i установлен в
NULL . |
strict |
Никакого предупреждения, никакой ошибки i установлен в
NULL . |
ERROR_FOR_DIVISION_BY_ZERO |
Предупреждение, но никакой ошибки i установлен в
NULL . |
strict,
ERROR_FOR_DIVISION_BY_ZERO |
Состояние ошибки: никакая строка не вставлена. |
13.20.4. Логика округления
Этот раздел обсуждает математику точности, округляющую для функции
ROUND() и для вставок в
столбцы с типами точного значения (
DECIMAL и integer).
Функция ROUND()
округляет по-разному в зависимости от того, точен ли
параметр или приблизителен:
Для чисел точного значения
ROUND() использует
правило округления половины вверх: значение с дробной частью .5
или больше округлено вверх к следующему целому числу, если положительное или
вниз к следующему целому числу, если отрицательное.
Значение с дробной частью меньше, чем .5 округлены в меньшую сторону к
следующему целому числу в соответствующую сторону.
- Для чисел приблизительной точности результат зависит от библиотеки C. На
многих системах это означает, что
ROUND() использует
правило округления к самому близкому значению:
значение с любой дробной частью округлено к самому близкому целому числу.
Следующие примеры показывают, как округление отличается для
точных и приблизительных чисел:
mysql> SELECT ROUND(2.5), ROUND(25E-1);
+------------+--------------+
| ROUND(2.5) | ROUND(25E-1) |
+------------+--------------+
| 3 | 2 |
+------------+--------------+
Для вставок в столбец DECIMAL
или целого числа цель точный тип данных, таким образом,
округлениея использует правило округления половины вверх
независимо от того, точно ли значение, которое будет
вставлено, или приблизительно:
mysql> CREATE TABLE t (d DECIMAL(10,0));
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t VALUES(2.5),(2.5E0);
Query OK, 2 rows affected, 2 warnings (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 2
mysql> SELECT d FROM t;
+---+
| d |
+---+
| 3 |
| 3 |
+---+
13.20.5. Примеры точной математики
Этот раздел обеспечивает некоторые примеры, которые показывают
математические результаты запроса точности в MySQL. Эти примеры демонстрируют
принципы, описанные в разделах
13.20.3 и
13.20.4.
Пример 1.
Числа используются с их точным значением как даны, когда возможно:
mysql> SELECT (.1 + .2) = .3;
+----------------+
| (.1 + .2) = .3 |
+----------------+
| 1 |
+----------------+
Для значений с плавающей запятой результаты неточны:
mysql> SELECT (.1E0 + .2E0) = .3E0;
+----------------------+
| (.1E0 + .2E0) = .3E0 |
+----------------------+
| 0 |
+----------------------+
Другой способ видеть различие в обработке точных и приблизительных
чисел состоит в том, чтобы добавить небольшое число к сумме много раз.
Рассмотрите следующую хранимую процедуру, которая добавляет
.0001 к переменным 1,000 раз.
CREATE PROCEDURE p ()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE d DECIMAL(10,4) DEFAULT 0;
DECLARE f FLOAT DEFAULT 0;
WHILE i < 10000 DO
SET d = d + .0001;
SET f = f + .0001E0;
SET i = i + 1;
END WHILE;
SELECT d, f;
END;
Сумма для обоих d и f
логически должна быть 1, но это истина только для десятичного вычисления.
Вычисление с плавающей запятой вводит маленькие ошибки:
+--------+------------------+
| d | f |
+--------+------------------+
| 1.0000 | 0.99999999999991 |
+--------+------------------+
Пример 2.
Умножение выполнено с масштабом, требуемым стандартным SQL. Таким образом,
для двух чисел X1 и X2
есть масштаб S1 и S2 ,
масштаб результата S1 +S2
:
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
| 0.0001 |
+-----------+
Пример 3.
Округление для чисел точного значения является четким:
Округление (например, функцией
ROUND() )
независимо от выполнения основной библиотеки C, это означает, что результаты
последовательны, независмо от платформы.
Округление для точных столбцов значений
(DECIMAL
и целые числа) использует правило округления половины вверх.
Значения с дробной частью .5 или больше округлены до самого близкого целого
числа в сторону от нуля, как показано здесь:
mysql> SELECT ROUND(2.5), ROUND(-2.5);
+------------+-------------+
| ROUND(2.5) | ROUND(-2.5) |
+------------+-------------+
| 3 | -3 |
+------------+-------------+
- Округление для значений с плавающей запятой пользуется библиотекой C,
которая на многих системах использует другую логику. Значения с любой дробной
частью на таких системах округлены к самому близкому числу:
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);
+--------------+---------------+
| ROUND(2.5E0) | ROUND(-2.5E0) |
+--------------+---------------+
| 2 | -2 |
+--------------+---------------+
Пример 4.
В строгом режиме, вставляя значение, которое вне диапазона для столбца, Вы
получите ошибку, а не усечение к легальному значению.
Когда MySQL не работает в строгом режиме, усечение к
легальному значению происходит:
mysql> SET sql_mode='';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t SET i = 128;
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SELECT i FROM t;
+-----+
| i |
+-----+
| 127 |
+-----+
1 row in set (0.00 sec)
Однако, ошибка происходит, если строгий режим активен:
mysql> SET sql_mode='STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t SET i = 128;
ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1
mysql> SELECT i FROM t;
Empty set (0.00 sec)
Пример 5.
В строгом режиме и с установленной опцией
ERROR_FOR_DIVISION_BY_ZERO деление на ноль вызывает ошибку, а
не результат NULL .
В нестрогом режиме у деления есть результат NULL :
mysql> SET sql_mode='';
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t SET i = 1/0;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT i FROM t;
+------+
| i |
+------+
| NULL |
+------+
1 row in set (0.03 sec)
Однако, деление на ноль ошибка, если надлежащие режимы SQL включены:
mysql> SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t SET i = 1 / 0;
ERROR 1365 (22012): Division by 0
mysql> SELECT i FROM t;
Empty set (0.01 sec)
Пример 6.
Литералы точного значения оценены как точные значения.
Числа приблизительной точности оценены, используя плавающую запятую, но
числа точного значения обработаны как
DECIMAL :
mysql> CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> DESCRIBE t;
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| a | decimal(2,1) unsigned | NO | | 0.0 | |
| b | double | NO | | 0 | |
+-------+-----------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
Пример 7.
Если параметр совокупной функции точный числовой тип, результат также точный
числовой тип, с масштабом, по крайней мере таким, как у параметра.
Рассмотрите эти запросы:
mysql> CREATE TABLE t (i INT, d DECIMAL, f FLOAT);
mysql> INSERT INTO t VALUES(1,1,1);
mysql> CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
Результат double только для параметра с плавающей запятой. Для точных
параметров типа результат также точный тип:
mysql> DESCRIBE y;
+--------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| AVG(i) | decimal(14,4) | YES | | NULL | |
| AVG(d) | decimal(14,4) | YES | | NULL | |
| AVG(f) | double | YES | | NULL | |
+--------+---------------+------+-----+---------+-------+
|
|