MySQL 8.0 リファレンスマニュアル


9.5 式

このセクションでは、式が MySQL で従う必要がある文法ルールをリストし、式に使用できる用語のタイプに関する追加情報を提供します。

式の構文

次の文法ルールは、MySQL で式の構文を定義します。 ここで示す文法は、MySQL ソース配布の sql/sql_yacc.yy ファイルで与えられた文法に基づいています。 一部の式の用語の詳細は、式の用語のノート を参照してください。

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.11「サーバー SQL モード」を参照してください。

式の用語のノート

リテラル値の構文については、セクション9.1「リテラル値」を参照してください。

識別子の構文については、セクション9.2「スキーマオブジェクト名」を参照してください。

変数には、ユーザー変数、システム変数、ストアドプログラムのローカル変数またはパラメータがあります。

param_marker は、準備されたステートメントでプレースホルダーに使用されているように ? です。 セクション13.5.1「PREPARE ステートメント」を参照してください。

(subquery) は、単一の値を返すサブクエリー、つまりスカラーサブクエリーを示します。 セクション13.2.11.1「スカラーオペランドとしてのサブクエリー」を参照してください。

{identifier expr} は、ODBC エスケープ構文であり、ODBC との互換性のために認められています。 値は expr です。 構文内の {および} 中カッコは文字どおりに記述する必要があります。構文の説明の他の場所で使用されているメタ構文ではありません。

match_exprMATCH 式を示します。 セクション12.10「全文検索関数」を参照してください。

case_exprCASE 式を示します。 セクション12.5「フロー制御関数」を参照してください。

interval_expr は時間間隔を表します。 時間間隔を参照してください。

時間間隔

式の interval_expr は時間間隔を表します。 間隔の構文は次のとおりです:

INTERVAL expr unit

expr は数量を表します。unit は、数量を解釈するための単位を表します。HOURDAYWEEK などの指定子です。 INTERVAL キーワードおよび unit 指定子では、大文字と小文字は区別されません。

次の表には、unit 値ごとに要求される形式の expr 引数を表示します。

表 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 は、他方の側の式が日付または日付間値である場合に、+ 演算子の一方の側で許可されます。 - 演算子では、間隔から日付または日付間値を抽出しても意味がないため、INTERVAL 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() 関数は、DATE_ADD() または DATE_SUB() と同じ種類の unit 指定子を使用しますが、日付演算を実行するのではなく、日付から部分を抽出します:

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 では間隔値の左端部分が省略されているとみなされます。 たとえば、DAY_SECONDunit を指定した場合は、expr の値には日、時間、分、秒の部分が含まれるとみなされます。 '1:10' のような値を指定すると、MySQL では日と時間の部分が欠落していて、値は分と秒を表しているとみなされます。 つまり、'1:10' DAY_SECOND は、'1:10' MINUTE_SECOND と同等の方法で解釈されます。 これは、MySQL で TIME 値が時間ではなく経過時間を表していると解釈される方法に類似しています。

expr は文字列として扱われるため、INTERVAL で文字列以外の値を指定する場合は注意してください。 たとえば、間隔指定子が HOUR_MINUTE の場合、6/4 は 6 時間 4 分として扱われますが、6/41.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 分として処理するには、小数点以下の桁数が 1 桁の 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'

時間部分が含まれるものを日付値に加算したり、日付値から減算したりすると、自動的に結果が日付時間値に変換されます。

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'

MONTHYEAR_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

関連キーワード:  expr, bit, INTERVAL, DAY, 間隔, 日付, セクション, HOUR, simple, unit