11.5 Выражения
В этом разделе перечислены правила грамматики, которым должны следовать выражения в MySQL, а также предоставлена дополнительная информация о типах терминов, которые могут встречаться в выражениях.
Синтаксис выражений
Следующие правила грамматики определяют синтаксис выражений в MySQL. Приведённая здесь грамматика основана на грамматике из файла sql/sql_yacc.yy в дистрибутивах исходного кода MySQL. Дополнительную информацию о некоторых терминах выражений можно найти в разделе Примечания к терминам выражений.
expr:
expr OR expr
| expr || expr
| expr XOR expr
| expr AND expr
| expr && expr
| NOT expr
| ! expr
| boolean_primary IS [NOT] {TRUE | FALSE | UNKNOWN}
| boolean_primary
boolean_primary:
boolean_primary IS [NOT] NULL
| boolean_primary <=> predicate
| boolean_primary comparison_operator predicate
| boolean_primary comparison_operator {ALL | ANY} (subquery)
| predicate
comparison_operator: = | >= | > | <= | < | <> | !=
predicate:
bit_expr [NOT] IN (subquery)
| bit_expr [NOT] IN (expr [, expr] ...)
| bit_expr [NOT] BETWEEN bit_expr AND predicate
| bit_expr SOUNDS LIKE bit_expr
| bit_expr [NOT] LIKE simple_expr [ESCAPE simple_expr]
| bit_expr [NOT] REGEXP bit_expr
| bit_expr
bit_expr:
bit_expr | bit_expr
| bit_expr & bit_expr
| bit_expr << bit_expr
| bit_expr >> bit_expr
| bit_expr + bit_expr
| bit_expr - bit_expr
| bit_expr * bit_expr
| bit_expr / bit_expr
| bit_expr DIV bit_expr
| bit_expr MOD bit_expr
| bit_expr % bit_expr
| bit_expr ^ bit_expr
| bit_expr + interval_expr
| bit_expr - interval_expr
| simple_expr
simple_expr:
literal
| identifier
| function_call
| simple_expr COLLATE collation_name
| param_marker
| variable
| simple_expr || simple_expr
| + simple_expr
| - simple_expr
| ~ simple_expr
| ! simple_expr
| BINARY simple_expr
| (expr [, expr] ...)
| ROW (expr, expr [, expr] ...)
| (subquery)
| EXISTS (subquery)
| {identifier expr}
| match_expr
| case_expr
| interval_expr
Справочную информацию об операторном приоритете смотрите в разделе Раздел 14.4.1, «Приоритет операторов». Приоритет и смысл некоторых операторов зависят от режима SQL:
По умолчанию,
||— логическийORоператор. При включённом режимеPIPES_AS_CONCAT,||выполняет конкатенацию строк с приоритетом между^и унарными операторами.По умолчанию,
!имеет более высокий приоритет, чемNOT. При включённом режимеHIGH_NOT_PRECEDENCE,!иNOTимеют одинаковый приоритет.
Смотрите Раздел 7.1.11, «Режим SQL сервера».
Примечания к терминам выражений
Синтаксис литералов см. в разделе Раздел 11.1, «Литералы».
Синтаксис идентификаторов см. в разделе Раздел 11.2, «Имена объектов схемы».
Переменные могут быть пользовательскими переменными, системными переменными или локальными переменными или параметрами хранимых программ:
Пользовательские переменные: Раздел 11.4, «Пользовательские переменные»
Системные переменные: Раздел 7.1.9, «Использование системных переменных»
Локальные переменные хранимых программ: Раздел 15.6.4.1, «Определение локальной переменной оператором DECLARE»
Параметры хранимых программ: Раздел 15.1.17, «Операторы CREATE PROCEDURE и CREATE FUNCTION»
param_marker является ?, используемой в подготовленных запросах в качестве плейсхолдера. Смотрите Раздел 15.5.1, «Оператор PREPARE».
( обозначает подзапрос, возвращающий одно значение; то есть скалярный подзапрос. Смотрите Раздел 15.2.15.1, «Подзапрос как скалярный операнд». subquery)
{ — это синтаксис экранирования ODBC и принимается для совместимости с ODBC. Значение равно identifier
expr}expr. Фигурные скобки { и } в синтаксисе должны быть написаны буквально; они не являются метасинтаксисом, как используется в других описаниях синтаксиса.
match_expr обозначает выражение MATCH. Смотрите Раздел 14.9, «Функции полнотекстового поиска».
case_expr обозначает выражение CASE. Смотрите Раздел 14.5, «Функции управления потоком».
interval_expr представляет временной интервал. Смотрите Временные интервалы.
Временные интервалы
interval_expr в выражениях представляет временной интервал. Интервалы имеют такой синтаксис:
INTERVAL expr unit
expr представляет величину. unit представляет единицу измерения для интерпретации величины; это спецификатор, такой как HOUR, DAY или WEEK. Ключевое слово INTERVAL и спецификатор unit нечувствительны к регистру.
В следующей таблице показан ожидаемый формат аргумента expr для каждого значения unit.
Таблица 11.2 Аргументы временного интервала и единиц измерения
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' |
MySQL допускает любые знаки препинания в качестве разделителей в формате expr. Предложенные разделители указаны в таблице.
Временные интервалы используются для определенных функций, таких как DATE_ADD() и DATE_SUB():
mysql> SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);
-> '2018-05-02'
mysql> SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);
-> '2017-05-01'
mysql> SELECT DATE_ADD('2020-12-31 23:59:59',
-> INTERVAL 1 SECOND);
-> '2021-01-01 00:00:00'
mysql> SELECT DATE_ADD('2018-12-31 23:59:59',
-> INTERVAL 1 DAY);
-> '2019-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('2025-01-01 00:00:00',
-> INTERVAL '1 1:1:1' DAY_SECOND);
-> '2024-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'
Временные арифметические операции также могут выполняться в выражениях с использованием INTERVAL вместе с оператором + или -:
date + INTERVAL expr unit
date - INTERVAL expr unit
INTERVAL разрешено по обе стороны оператора expr
unit+, если выражение с другой стороны — значение даты или datetime. Для оператора - INTERVAL разрешено только справа, так как вычитание значения даты или datetime из интервала не имеет смысла. expr
unit
mysql> SELECT '2018-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '2019-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '2018-12-31';
-> '2019-01-01'
mysql> SELECT '2025-01-01' - INTERVAL 1 SECOND;
-> '2024-12-31 23:59:59'
Функция EXTRACT() использует те же виды спецификаторов unit, что и DATE_ADD() или DATE_SUB(), но извлекает части из даты, а не выполняет арифметические операции с датой:
mysql> SELECT EXTRACT(YEAR FROM '2019-07-02');
-> 2019
mysql> SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');
-> 201907
Временные интервалы могут использоваться в операторах CREATE
EVENT:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
Если вы задаёте значение интервала, которое слишком короткое (не включает все части интервала, которые ожидаются от ключевого слова 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' интерпретируется как 6 часов, 4 минуты, тогда как 6/4 вычисляется как 1.5000 и интерпретируется как 1 час, 5000 минут:
mysql> SELECT '6/4', 6/4;
-> 1.5000
mysql> SELECT DATE_ADD('2019-01-01', INTERVAL '6/4' HOUR_MINUTE);
-> '2019-01-01 06:04:00'
mysql> SELECT DATE_ADD('2019-01-01', INTERVAL 6/4 HOUR_MINUTE);
-> '2019-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('2023-01-01', INTERVAL 1 DAY);
-> '2023-01-02'
mysql> SELECT DATE_ADD('2023-01-01', INTERVAL 1 HOUR);
-> '2023-01-01 01:00:00'
Если вы добавляете MONTH, YEAR_MONTH или YEAR, и полученная дата имеет день, больший, чем максимальный день для нового месяца, день корректируется до максимального числа дней в новом месяце:
mysql> SELECT DATE_ADD('2019-01-30', INTERVAL 1 MONTH);
-> '2019-02-28'
Арифметические операции с датой требуют полных дат и не работают с неполными датами, такими как '2016-07-00' или неправильно сформированными датами:
mysql> SELECT DATE_ADD('2016-07-00', INTERVAL 1 DAY);
-> NULL
mysql> SELECT '2005-03-32' + INTERVAL 1 MONTH;
-> NULL
© 2025 Oracle
Licensed under the GPLv2 License.