• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 表达式

    本节列出了MySQL中表达式必须遵循的语法规则,并提供了有关表达式中可能出现的术语类型的其他信息。

    • 表达式语法
    • 表达术语注释
    • 时间间隔

    表达式语法

    以下语法规则定义了MySQL中的表达式语法。此处显示的语法基于sql/sql_yacc.yyMySQL源代码分发文件中给出的语法。有关某些表达术语的更多信息,请参见表达术语注释。

    expr:
        expr OR expr
      | expr || expr
      | expr XOR expr
      | expr AND expr
      | expr && expr
      | NOT expr
      | ! expr
      |  oolean_primary IS [NOT] {TRUE | FALSE | UNKNOWN}
      |  oolean_primary
    
     oolean_primary:
         oolean_primary IS [NOT] NULL
      |  oolean_primary <=> predicate
      |  oolean_primary comparison_operator predicate
      |  oolean_primary comparison_operator {ALL | ANY} (subquery)
      | predicate
    
    comparison_operator: = | >= | > | <= | < | <> | !=
    
    predicate:
         it_expr [NOT] IN (subquery)
      |  it_expr [NOT] IN (expr [, expr] ...)
      |  it_expr [NOT] BETWEEN  it_expr AND predicate
      |  it_expr SOUNDS LIKE  it_expr
      |  it_expr [NOT] LIKE simple_expr [ESCAPE simple_expr]
      |  it_expr [NOT] REGEXP  it_expr
      |  it_expr
    
     it_expr:
         it_expr |  it_expr
      |  it_expr &  it_expr
      |  it_expr <<  it_expr
      |  it_expr >>  it_expr
      |  it_expr 	+  it_expr
      |  it_expr -  it_expr
      |  it_expr *  it_expr
      |  it_expr /  it_expr
      |  it_expr DIV  it_expr
      |  it_expr MOD  it_expr
      |  it_expr %  it_expr
      |  it_expr ^  it_expr
      |  it_expr 	+ interval_expr
      |  it_expr - interval_expr
      | simple_expr
    
    simple_expr:
        literal
      | identifier
      |  unction_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
    

    有关运算符的优先级,请参见“运算符的优先级”。一些运算符的优先级和含义取决于SQL模式:

    • 默认情况下,||是逻辑OR运算符。与PIPES_AS_CONCAT启用,||是字符串连接,与之间的优先级^和元运算符。
    • 默认情况下,!其优先级高于NOT。随着HIGH_NOT_PRECEDENCE启用,!并且NOT具有相同的优先级。

    请参见“服务器SQL模式”。

    表达术语注释

    有关文字值的语法,请参见“文字值”。

    有关标识符语法,请参见“模式对象名称”。

    变量可以是用户变量,系统变量或存储的程序局部变量或参数:

    • 用户变量:“用户定义的变量”
    • 系统变量:“使用系统变量”
    • 存储的程序局部变量:“局部变量DECLARE语句”
    • 存储的程序参数:“ CREATE PROCEDURE和CREATE FUNCTION语句”

    param_marker?如在用于占位符准备语句使用。请参见“ PREPARE语句”。

    (subquery)指示返回单个值的子查询;也就是标量子查询。请参见“作为标量操作数的子查询”。

    {identifierexpr}是ODBC转义语法,并且为ODBC兼容性而接受。值是expr。该{}在语法花括号应当从字面上写的;它们不是语法描述中其他地方使用的元语法。

    match_expr表示一个MATCH表达式。请参见“全文搜索功能”。

    case_expr表示一个CASE表达式。请参见“流程控制语句”。

    interval_expr代表时间间隔。请参阅时间间隔。

    时间间隔

    interval_expr表达式中的表示时间间隔。间隔具有以下语法:

    INTERVAL expr unit
    

    expr代表数量。unit代表解释数量的单位;它是一个说明符如HOURDAY,或WEEK。该INTERVAL关键字和unit符不区分大小写。

    下表显示了expr每个unit值的参数的预期形式。

    表9.2时间间隔表达式和单位参数

    unit预期expr格式
    MICROSECONDMICROSECONDS
    SECONDSECONDS
    MINUTEMINUTES
    HOURHOURS
    DAYDAYS
    WEEKWEEKS
    MONTHMONTHS
    QUARTERQUARTERS
    YEARYEARS
    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 +or -运算符一起使用:

    date 	+ INTERVAL expr unit
    date - INTERVAL expr unit
    

    INTERVAL exprunit +如果另一侧的表达式是日期或日期时间值,则在运算符的任一侧都允许使用。对于-操作员,只允许在右侧使用,因为从间隔中减去日期或日期时间值没有意义。INTERVAL exprunit

    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 myschem .mytable SET mycol = mycol 	+ 1;
    

    如果您指定的间隔值太短(不包括unit关键字期望的所有间隔部分),MySQL会假定您已忽略了间隔值的最左侧部分。例如,如果您指定unitDAY_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'
    

    如果您向日期值添加或减去包含时间部分的内容,则结果将自动转换为日期时间值:

    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_MONTHYEAR,并且结果日期的天数大于新月的最大天数,则该天将调整为新月的最大天数:

    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