Spec-Zone.ru › MySQL 5.7

9.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

Для порядка приоритета операторов см. Раздел 12.4.1, «Порядок приоритета операторов». Порядок приоритета и значение некоторых операторов зависят от SQL-режима:

  • По умолчанию, || является логическим OR оператором. При включенном PIPES_AS_CONCAT, || является оператором конкатенации строк с приоритетом между ^ и унарными операторами.

  • По умолчанию, ! имеет более высокий приоритет, чем NOT. При включенном HIGH_NOT_PRECEDENCE, ! и NOT имеют одинаковый приоритет.

См. Раздел 5.1.10, «Серверные SQL-режимы».

Примечания к терминам выражений

Для синтаксиса литералов см. Раздел 9.1, «Литеральные значения».

Для синтаксиса идентификаторов см. Раздел 9.2, «Имена объектов схемы».

Переменные могут быть пользовательскими, системными или локальными переменными или параметрами хранимых программ:

  • Пользовательские переменные: Раздел 9.4, «Пользовательские переменные»

  • Системные переменные: Раздел 5.1.8, «Использование системных переменных»

  • Локальные переменные хранимых программ: Раздел 13.6.4.1, «Определение локальной переменной оператором DECLARE»

  • Параметры хранимых программ: Раздел 13.1.16, «Операторы CREATE PROCEDURE и CREATE FUNCTION»

param_marker является ?, используемым в подготовленных запросах в качестве заполнительных значений. См. Раздел 13.5.1, «Оператор PREPARE».

(subquery) обозначает подзапрос, возвращающий единственное значение; то есть скалярный подзапрос. См. Раздел 13.2.10.1, «Подзапрос как скалярный операнд».

{identifier expr} — синтаксис ODBC для экранирования и принимается для совместимости с ODBC. Значение равно expr. Фигурные скобки { и } в синтаксисе должны быть записаны буквально; они не являются метасинтаксисом, как используется в других описаниях синтаксиса.

match_expr обозначает выражение MATCH. См. Раздел 12.9, «Функции полнотекстового поиска».

case_expr обозначает выражение CASE. См. Раздел 12.5, «Функции управления потоком».

interval_expr представляет временной интервал. См. Временные интервалы.

END_OF_DOCUMENT_MARKER

Временные интервалы

interval_expr в выражениях представляет временной интервал. Интервалы имеют следующий синтаксис:

INTERVAL expr unit

expr представляет величину. unit представляет единицу измерения для интерпретации величины; это спецификатор, такой как HOUR, DAY или WEEK. Ключевое слово INTERVAL и спецификатор unit нечувствительны к регистру.

В следующей таблице показан ожидаемый формат аргумента expr для каждого значения unit.

Таблица 9.2 Аргументы временного интервала и единицы измерения

Таблица 9.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 expr unit разрешено только справа, так как вычитание значения даты или datetime из интервала не имеет смысла.

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.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/expressions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API