MySQL8-中文参考-四十七-

49 阅读1小时+

MySQL8 中文参考(四十七)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

14.2 可加载函数参考

原文:dev.mysql.com/doc/refman/8.0/en/loadable-function-reference.html

下表列出了每个可在运行时加载的函数,并提供了每个函数的简短描述。有关列出内置函数和运算符的表格,请参见第 14.1 节,“内置函数和运算符参考”

有关可加载函数的一般信息,请参见第 7.7 节,“MySQL 服务器可加载函数”。

表 14.2 可加载函数

名称描述引入版本废弃版本
asymmetric_decrypt()使用私钥或公钥解密密文
asymmetric_derive()从非对称密钥派生对称密钥
asymmetric_encrypt()使用私钥或公钥加密明文
asymmetric_sign()从摘要生成签名
asymmetric_verify()验证签名是否匹配摘要
asynchronous_connection_failover_add_managed()将一个受管组中的复制源服务器添加到源列表8.0.23
asynchronous_connection_failover_add_source()将一个复制源服务器添加到源列表8.0.22
asynchronous_connection_failover_delete_managed()从源列表中删除受管复制源服务器组8.0.23
asynchronous_connection_failover_delete_source()从源列表中删除一个复制源服务器8.0.22
audit_api_message_emit_udf()向审计日志添加消息事件
audit_log_encryption_password_get()获取审计日志加密密码
audit_log_encryption_password_set()设置审计日志加密密码
audit_log_filter_flush()刷新审计日志过滤表
audit_log_filter_remove_filter()移除审计日志过滤器
audit_log_filter_remove_user()从用户中取消分配审计日志过滤器
audit_log_filter_set_filter()定义审计日志过滤器
audit_log_filter_set_user()为用户分配审计日志过滤器
audit_log_read()返回审计日志记录
audit_log_read_bookmark()最近审计日志事件的书签
audit_log_rotate()旋转审计日志文件
create_asymmetric_priv_key()创建私钥
create_asymmetric_pub_key()创建公钥
create_dh_parameters()生成共享 DH 密钥
create_digest()从字符串生成摘要
firewall_group_delist()从防火墙组配置文件中移除帐户8.0.23
firewall_group_enlist()将帐户添加到防火墙组配置文件8.0.23
flush_rewrite_rules()将 rewrite_rules 表加载到 Rewriter 缓存中
gen_blacklist()执行字典术语替换8.0.23
gen_blocklist()执行字典术语替换8.0.33
gen_blocklist()执行字典术语替换8.0.23
gen_dictionary()从字典中返回随机术语8.0.33
gen_dictionary_drop()从注册表中移除字典
gen_dictionary_load()将字典加载到注册表中
gen_dictionary()从字典中返回随机术语
gen_range()在范围内生成随机数8.0.33
gen_range()在范围内生成随机数
gen_rnd_canada_sin()生成随机加拿大社会保险号码8.0.33
gen_rnd_email()生成随机电子邮件地址8.0.33
gen_rnd_email()生成随机电子邮件地址
gen_rnd_iban()生成随机国际银行帐号8.0.33
gen_rnd_pan()生成随机支付卡主帐号8.0.33
gen_rnd_pan()生成随机支付卡主帐号
gen_rnd_ssn()生成随机美国社会安全号码8.0.33
gen_rnd_ssn()生成随机美国社会安全号码
gen_rnd_uk_nin()生成随机英国国民保险号码8.0.33
gen_rnd_us_phone()生成随机美国电话号码8.0.33
gen_rnd_us_phone()生成随机美国电话号码
gen_rnd_uuid()生成随机通用唯一标识符8.0.33
group_replication_disable_member_action()启用成员操作,使成员在指定情况下不执行
group_replication_enable_member_action()在指定情况下启用成员操作
group_replication_get_communication_protocol()返回 Group Replication 协议版本
group_replication_get_write_concurrency()返回可并行执行的最大共识实例数
group_replication_reset_member_actions()将成员操作配置重置为默认设置
group_replication_set_as_primary()将组成员指定为新主
group_replication_set_communication_protocol()设置组复制协议版本
group_replication_set_write_concurrency()设置可以并行执行的最大一致性实例数
group_replication_switch_to_multi_primary_mode()将组从单主模式切换到多主模式
group_replication_switch_to_single_primary_mode()将组从多主模式切换到单主模式
keyring_aws_rotate_cmk()旋转 AWS 客户主密钥
keyring_aws_rotate_keys()旋转 keyring_aws 存储文件中的钥匙
keyring_hashicorp_update_config()导致运行时 keyring_hashicorp 重新配置
keyring_key_fetch()获取钥匙环钥匙值
keyring_key_generate()生成随机钥匙环钥匙
keyring_key_length_fetch()返回钥匙环钥匙长度
keyring_key_remove()移除钥匙环钥匙
keyring_key_store()在钥匙环中存储钥匙
keyring_key_type_fetch()返回钥匙环钥匙类型
load_rewrite_rules()重写插件辅助例程
mask_canada_sin()遮蔽加拿大社会保险号码8.0.33
mask_iban()遮蔽国际银行账号8.0.33
mask_inner()遮蔽字符串的内部部分8.0.33
mask_inner()遮蔽字符串的内部部分
mask_outer()遮蔽字符串的左右部分8.0.33
mask_outer()遮蔽字符串的左右部分
mask_pan()遮蔽支付卡主帐号部分字符串8.0.33
mask_pan()遮蔽支付卡主帐号部分字符串
mask_pan_relaxed()遮蔽支付卡主帐号部分字符串8.0.33
mask_pan_relaxed()遮蔽支付卡主帐号部分字符串
mask_ssn()遮蔽美国社会安全号码8.0.33
mask_ssn()遮蔽美国社会安全号码
mask_uk_nin()遮蔽英国国民保险号码8.0.33
mask_uuid()遮蔽字符串的通用唯一标识符部分8.0.33
masking_dictionary_remove()从数据库表中删除字典8.0.33
masking_dictionary_term_add()向字典中添加新术语8.0.33
masking_dictionary_term_remove()从字典中删除现有术语8.0.33
mysql_firewall_flush_status()重置防火墙状态变量
mysql_query_attribute_string()获取查询属性值8.0.23
normalize_statement()将 SQL 语句规范化为摘要形式
read_firewall_group_allowlist()更新防火墙组配置文件记录语句缓存8.0.23
read_firewall_groups()更新防火墙组配置文件缓存8.0.23
read_firewall_users()更新防火墙账户配置文件缓存8.0.26
read_firewall_whitelist()更新防火墙账户配置文件记录语句缓存8.0.26
service_get_read_locks()获取锁定服务共享锁
service_get_write_locks()获取锁定服务独占锁
service_release_locks()释放锁定服务锁
set_firewall_group_mode()建立防火墙组配置操作模式8.0.23
set_firewall_mode()建立防火墙账户配置操作模式8.0.26
version_tokens_delete()从版本令牌列表中删除令牌
version_tokens_edit()修改版本令牌列表
version_tokens_lock_exclusive()获取版本令牌的独占锁
version_tokens_lock_shared()获取版本令牌的共享锁
version_tokens_set()设置版本令牌列表
version_tokens_show()返回版本令牌列表
version_tokens_unlock()释放版本令牌锁
名称描述引入版本废弃版本

14.3 表达式求值中的类型转换

原文:dev.mysql.com/doc/refman/8.0/en/type-conversion.html

当使用具有不同类型操作数的运算符时,会发生类型转换以使操作数兼容。一些转换会隐式发生。例如,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,结果为真。不需要转换。

  • 如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。

  • 如果两个参数都是整数,则将它们作为整数进行比较。

  • 如果十六进制值与数字进行比较,则将其视为二进制字符串。

  • 如果其中一个参数是TIMESTAMPDATETIME列,另一个参数是常量,则在执行比较之前将常量转换为时间戳。这样做是为了更符合 ODBC 标准。但对于IN()的参数不会执行此操作。为了安全起见,在进行比较时,始终使用完整的日期、日期或时间字符串。例如,当使用BETWEEN与日期或时间值时,使用CAST()将值显式转换为所需的数据类型以获得最佳结果。

    来自表或表的单行子查询不被视为常量。例如,如果子查询返回一个整数用于与DATETIME值进行比较,则比较将作为两个整数进行。整数不会转换为时间值。要将操作数作为DATETIME值进行比较,请使用CAST()将子查询值显式转换为DATETIME

  • 如果其中一个参数是十进制值,则比较取决于另一个参数。如果另一个参数是十进制或整数值,则将参数作为十进制值进行比较,如果另一个参数是浮点值,则将参数作为浮点值进行比较。

  • 在所有其他情况下,参数将作为浮点(双精度)数进行比较。例如,字符串和数字操作数的比较将作为浮点数的比较进行。

有关从一种时间类型转换为另一种时间类型的值的转换信息,请参见第 13.2.8 节,“日期和时间类型之间的转换”。

JSON 值的比较分为两个级别。第一级别的比较基于比较值的 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'

浮点数和大整数类型的比较是近似的,因为在比较之前整数被转换为双精度浮点数,而双精度浮点数无法精确表示所有 64 位整数。例如,整数值 2⁵³ + 1 无法表示为浮点数,在浮点比较之前会被四舍五入为 2⁵³或 2⁵³ + 2,具体取决于平台。

仅以以下比较中的第一个比较相等的值,但两个比较都返回 true(1):

mysql> SELECT '9223372036854775807' = 9223372036854775807;
 -> 1
mysql> SELECT '9223372036854775807' = 9223372036854775806;
 -> 1

当从字符串到浮点数和从整数到浮点数的转换发生时,它们不一定以相同的方式发生。整数可能由 CPU 转换为浮点数,而字符串则通过涉及浮点数乘法的操作逐位转换。此外,结果可能受到诸如计算机架构、编译器版本或优化级别等因素的影响。避免此类问题的一种方法是使用CAST()以便值不会隐式转换为浮点数:

mysql> SELECT CAST('9223372036854775807' AS UNSIGNED) = 9223372036854775806;
 -> 0

有关浮点比较的更多信息,请参见第 B.3.4.8 节,“浮点值的问题”。

服务器包含dtoa,一个转换库,提供了在字符串或DECIMAL - DECIMAL, NUMERIC")值和近似值(FLOAT - FLOAT, DOUBLE")/DOUBLE - FLOAT, DOUBLE"))之间改进转换的基础:

  • 跨平台的一致转换结果,消除了 Unix 与 Windows 转换差异,例如。

  • 在以前结果未提供足够精度的情况下准确表示值,例如接近 IEEE 极限的值。

  • 将数字转换为具有最佳可能精度的字符串格式。dtoa的精度始终与标准 C 库函数相同或更好。

由于此库产生的转换在某些情况下与非dtoa结果不同,因此存在应用程序不兼容的潜在可能性,这些应用程序依赖于以前的结果。例如,依赖于以前转换的特定精确结果的应用程序可能需要调整以适应额外的精度。

dtoa库提供了以下属性的转换。D 表示具有DECIMAL - DECIMAL, NUMERIC")或字符串表示的值,F 表示本机二进制(IEEE)格式的浮点数。

  • F -> D 转换是以最佳可能精度进行的,返回 D 作为最短字符串,当读回并按 IEEE 指定的本机二进制格式四舍五入到最接近的值时,会产生 F

  • D -> F 转换是这样进行的,使得 F 是输入十进制字符串 D 最接近的本机二进制数。

这些属性意味着 F -> D -> F 转换是无损失的,除非 F-inf+infNaN。后三个值不受支持,因为 SQL 标准将它们定义为FLOAT - FLOAT, DOUBLE")或DOUBLE - FLOAT, DOUBLE")的无效值。

对于 D -> F -> D 转换,无损失的一个充分条件是 D 使用 15 位或更少的精度,不是非规格化值,也不是 -inf+infNaN。在某些情况下,即使 D 的精度超过 15 位,转换也是无损失的,但并非总是如此。

将数值或时间值隐式转换为字符串会产生一个具有由character_set_connectioncollation_connection系统变量确定的字符集和排序规则的值。(这些变量通常使用SET NAMES设置。有关连接字符集的信息,请参见第 12.4 节,“连接字符集和排序规则”。)

这意味着这样的转换会产生一个字符(非二进制)字符串(一个CHARVARCHARLONGTEXT值),除非连接字符集设置为binary。在这种情况下,转换结果是一个二进制字符串(一个BINARYVARBINARYLONGBLOB值)。

对于整数表达式,关于表达式评估的前述备注在表达式赋值方面有所不同;例如,在这样的语句中:

CREATE TABLE t SELECT *integer_expr*;

在这种情况下,由表达式生成的列中的表具有INT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")或BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")类型,具体取决于整数表达式的长度。如果表达式的最大长度不适合INT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"),则改用BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")。长度取自SELECT结果集元数据的max_length值(参见 C API 基本数据结构)。这意味着您可以通过使用足够长的表达式来强制使用BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")而不是INT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT"):

CREATE TABLE t SELECT 000000000000000000000;

14.4 操作符

原文:dev.mysql.com/doc/refman/8.0/en/non-typed-operators.html

14.4.1 操作符优先级

14.4.2 比较函数和操作符

14.4.3 逻辑操作符

14.4.4 赋值操作符

表格 14.3 操作符

名称描述引入版本废弃版本
&按位与
>大于操作符
>>右移操作符
>=大于等于操作符
<小于操作符
<>, !=不等于操作符
<<左移操作符
<=小于等于操作符
<=>NULL 安全等于操作符
%, MOD取模操作符
*乘法操作符
+加法操作符
-减法操作符
-改变参数的符号
->在评估路径后从 JSON 列返回值;相当于 JSON_EXTRACT()。
->>在评估路径并取消引用结果后从 JSON 列返回值;相当于 JSON_UNQUOTE(JSON_EXTRACT())。
/除法操作符
:=赋值操作符
=赋值操作符(作为 SET 语句的一部分,或作为 UPDATE 语句中的 SET 子句的一部分)
=等于操作符
^按位异或
AND, &&逻辑与
BETWEEN ... AND ...判断一个值是否在一系列值范围内
BINARY将字符串转换为二进制字符串8.0.27
CASECase 操作符
DIV整数除法
IN()值是否在一组值内
IS测试值是否为布尔值
IS NOT测试值是否为布尔值
IS NOT NULL非空值测试
IS NULL空值测试
LIKE简单模式匹配
MEMBER OF()如果第一个操作数匹配作为第二个操作数传递的 JSON 数组的任何元素,则返回 true (1),否则返回 false (0)8.0.17
NOT, !取反值
NOT BETWEEN ... AND ...值是否不在一系列值范围内
NOT IN()值是否不在一组值内
NOT LIKE简单模式匹配的否定
NOT REGEXPREGEXP 的否定
OR, &#124;&#124;逻辑或
REGEXP字符串是否匹配正则表达式
RLIKE字符串是否匹配正则表达式
SOUNDS LIKE比较声音
XOR逻辑异或
&#124;按位或
~按位取反
Name描述引入废弃

14.4.1 运算符优先级

原文:dev.mysql.com/doc/refman/8.0/en/operator-precedence.html

运算符优先级按照以下列表从最高优先级到最低优先级显示。在同一行上显示在一起的运算符具有相同的优先级。

INTERVAL
BINARY, COLLATE
!
- (unary minus), ~ (unary bit inversion)
^
*, /, DIV, %, MOD
-, +
<<, >>
&
|
= (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN, MEMBER OF
BETWEEN, CASE, WHEN, THEN, ELSE
NOT
AND, &&
XOR
OR, ||
= (assignment), :=

=的优先级取决于它是作为比较运算符(=)还是作为赋值运算符(=)使用。当作为比较运算符使用时,它与<=>>=><=<<>!=ISLIKEREGEXPIN()具有相同的优先级。当作为赋值运算符使用时,它与:=具有相同的优先级。“变量赋值的 SET 语法”和“用户定义变量”部分解释了 MySQL 如何确定应该应用哪种=的解释。

对于在表达式中具有相同优先级的运算符,计算从左到右进行,但赋值运算符的计算是从右到左进行。

一些运算符的优先级和含义取决于 SQL 模式:

  • 默认情况下,||是逻辑OR运算符。启用PIPES_AS_CONCAT后,||是字符串连接运算符,优先级介于^和一元运算符之间。

  • 默认情况下,!的优先级高于NOT。启用HIGH_NOT_PRECEDENCE后,!NOT具有相同的优先级。

参见“服务器 SQL 模式”第 7.1.11 节。

运算符的优先级确定了表达式中项的计算顺序。要覆盖这个顺序并显式地分组项,请使用括号。例如:

mysql> SELECT 1+2*3;
 -> 7
mysql> SELECT (1+2)*3;
 -> 9

14.4.2 比较函数和运算符

原文:dev.mysql.com/doc/refman/8.0/en/comparison-operators.html

表 14.4 比较运算符

名称描述
>大于运算符
>=大于或等于运算符
<小于运算符
<>, !=不等运算符
<=小于或等于运算符
<=>NULL 安全等于运算符
=等于运算符
BETWEEN ... AND ...值是否在一系列值范围内
COALESCE()返回第一个非 NULL 参数
GREATEST()返回最大的参数
IN()值是否在一组值内
INTERVAL()返回小于第一个参数的参数的索引
IS测试值是否为布尔值
IS NOT测试值是否为布尔值
IS NOT NULL非 NULL 值测试
IS NULLNULL 值测试
ISNULL()测试参数是否为 NULL
LEAST()返回最小的参数
LIKE简单的模式匹配
NOT BETWEEN ... AND ...值是否不在一系列值范围内
NOT IN()值是否不在一组值内
NOT LIKE简单模式匹配的否定
STRCMP()比较两个字符串
名称描述

比较操作的结果为1TRUE)、0FALSE)或NULL。这些操作适用于数字和字符串。字符串会根据需要自动转换为数字,数字也会转换为字符串。

下列关系比较运算符可用于比较标量操作数以及行操作数:

=  >  <  >=  <=  <>  !=

本节后面对这些运算符的描述详细说明了它们如何与行操作数一起工作。有关在行子查询上下文中的行比较的其他示例,请参见第 15.2.15.5 节,“行子查询”。

本节中的一些函数返回除1TRUE)、0FALSE)或NULL之外的值。LEAST()GREATEST()就是这样的函数的例子;第 14.3 节,“表达式评估中的类型转换”描述了这些函数执行比较操作以确定它们的返回值的规则。

注意

在 MySQL 的早期版本中,当评估包含LEAST()GREATEST()的表达式时,服务器尝试猜测函数的使用上下文,并将函数的参数强制转换为整个表达式的数据类型。例如,对于LEAST("11", "45", "2")的参数将作为字符串进行评估和排序,因此该表达式返回"11"。在 MySQL 8.0.3 及更早版本中,当评估表达式LEAST("11", "45", "2") + 0时,服务器在对其进行排序之前将参数转换为整数(预期将整数 0 添加到结果),从而返回 2。

从 MySQL 8.0.4 开始,服务器不再尝试以这种方式推断上下文。相反,函数将使用提供的参数执行,仅在它们不全为相同类型时对一个或多个参数执行数据类型转换。现在,任何使用返回值的表达式强制执行的类型强制转换都是在函数执行后执行的。这意味着,在 MySQL 8.0.4 及更高版本中,LEAST("11", "45", "2") + 0计算为"11" + 0,因此为整数 11。 (Bug #83895, Bug #25123839)

要将值转换为特定类型以进行比较,可以使用CAST()函数。字符串值可以使用CONVERT()将其转换为不同的字符集。参见第 14.10 节,“转换函数和运算符”。

默认情况下,字符串比较不区分大小写,并使用当前字符集。默认为utf8mb4

  • =

    等于:

    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-安全等于。此运算符执行类似于=运算符的相等比较,但如果两个操作数都为NULL,则返回1而不是NULL,如果一个操作数为NULL,则返回0而不是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))
    
  • *expr* BETWEEN *min* AND *max*

    如果*expr大于或等于minexpr小于或等于max*,BETWEEN返回1,否则返回0。如果所有参数类型相同,则这等同于表达式(*min* <= *expr* AND *expr* <= *max*)。否则,根据第 14.3 节,“表达式求值中的类型转换”中描述的规则进行类型转换,但应用于所有三个参数。

    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值。如果在与DATE比较中使用字符串常量如'2001-1-1',则将字符串转换为DATE

  • *expr* NOT BETWEEN *min* AND *max*

    这与NOT (*expr* BETWEEN *min* AND *max*)相同。

  • COALESCE(*value*,...)

    返回列表中第一个非NULL值,如果没有非NULL值则返回NULL

    COALESCE()的返回类型是参数类型的聚合类型。

    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*,...)

    如果*expr*等于IN()列表中的任何一个值,则返回1(true),否则返回0(false)。

    根据第 14.3 节,“表达式评估中的类型转换”中描述的规则进行类型转换,应用于所有参数。如果IN()列表中的值不需要类型转换,它们都是相同类型的非JSON常量,并且*expr可以与它们中的每一个作为相同类型的值进行比较(可能经过类型转换),则会进行优化。列表中的值被排序,使用二分查找来搜索expr*,使得IN()操作非常快速。

    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()列表中混合引号和非引号值,因为引号值(如字符串)和非引号值(如数字)的比较规则不同。因此,混合类型可能导致不一致的结果。例如,不要像这样编写IN()表达式:

    SELECT val1 FROM tbl1 WHERE val1 IN (1,2,'a');
    

    相反,应该这样写:

    SELECT val1 FROM tbl1 WHERE val1 IN ('1','2','a');
    

    隐式类型转换可能会产生令人费解的结果:

    mysql> SELECT 'a' IN (0), 0 IN ('b');
     -> 1, 1
    

    在这两种情况下,比较值被转换为浮点值,每种情况下均产生 0.0,并且比较结果为 1(true)。

    IN()列表中的值的数量仅受max_allowed_packet值的限制。

    为了符合 SQL 标准,IN()不仅在左侧表达式为NULL时返回NULL,而且在列表中找不到匹配项且列表中的一个表达式为NULL时也返回NULL

    IN()语法也可以用于编写某些类型的子查询。请参见第 15.2.15.3 节,“带有 ANY、IN 或 SOME 的子查询”。

  • *expr* NOT IN (*value*,...)

    这与NOT (*expr* IN (*value*,...))相同。

  • INTERVAL(*N*,*N1*,*N2*,*N3*,...)

    如果*N* ≤ N1,则返回0,如果*N* ≤ N2等等,或者如果NNULL,则返回-1。所有参数都被视为整数。对于这个函数能够正确工作,需要满足N1N2N3...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
    
  • IS *boolean_value*

    测试一个值是否等于布尔值,其中*boolean_value*可以是TRUEFALSEUNKNOWN

    mysql> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
     -> 1, 1, 1
    
  • IS NOT *boolean_value*

    测试一个值是否等于布尔值,其中*boolean_value*可以是TRUEFALSEUNKNOWN

    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()函数的结果相同。有关详细信息,包括多行插入后的返回值,请参见第 14.15 节,“信息函数”。如果没有成功插入AUTO_INCREMENT值,则SELECT语句不返回任何行。

      通过设置sql_auto_is_null = 0可以禁用使用IS NULL比较来检索AUTO_INCREMENT值的行为。请参见第 7.1.8 节,“服务器系统变量”。

      sql_auto_is_null的默认值为 0。

    • 对于声明为NOT NULLDATEDATETIME列,可以通过类似以下语句找到特殊日期'0000-00-00'

      SELECT * FROM *tbl_name* WHERE *date_column* IS NULL
      

      这是为了使一些 ODBC 应用程序正常工作而需要的,因为 ODBC 不支持'0000-00-00'日期值。

      参见获取自增值,以及 Connector/ODBC 连接参数中FLAG_AUTO_IS_NULL选项的描述。

  • IS NOT NULL

    测试一个值是否不为NULL

    mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
     -> 1, 1, 0
    
  • ISNULL(*expr*)

    如果*expr*为NULLISNULL()返回1,否则返回0

    mysql> SELECT ISNULL(1+1);
     -> 0
    mysql> SELECT ISNULL(1/0);
     -> 1
    

    ISNULL()可用于代替=来测试一个值是否为NULL。(使用=将值与NULL进行比较总是返回NULL。)

    ISNULL()函数与IS NULL比较运算符共享一些特殊行为。请参见IS NULL的描述。

  • LEAST(*value1*,*value2*,...)

    对于两个或更多参数,返回最小值的参数。参数将根据以下规则进行比较:

    • 如果任何参数为NULL,则结果为NULL。不需要进行比较。

    • 如果所有参数都是整数值,则它们将作为整数进行比较。

    • 如果至少一个参数是双精度,则它们将作为双精度值进行比较。否则,如果至少一个参数是DECIMAL - DECIMAL, NUMERIC")值,则它们将作为DECIMAL - DECIMAL, NUMERIC")值进行比较。

    • 如果参数包含数字和字符串的混合,则它们将作为字符串进行比较。

    • 如果任何参数是非二进制(字符)字符串,则参数将作为非二进制字符串进行比较。

    • 在所有其他情况下,参数将作为二进制字符串进行比较。

    LEAST()的返回类型是比较参数类型的聚合类型。

    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'
    

14.4.3 逻辑运算符

原文:dev.mysql.com/doc/refman/8.0/en/logical-operators.html

表 14.5 逻辑运算符

名称描述
AND, &&逻辑 AND
NOT, !取反值
OR, &#124;&#124;逻辑 OR
XOR逻辑 XOR

在 SQL 中,所有逻辑运算符的计算结果为TRUEFALSENULLUNKNOWN)。在 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。如果操作数为0,则计算结果为1,如果操作数为非零,则为0NOT 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相同。

    ! 运算符是 MySQL 的非标准扩展。从 MySQL 8.0.17 开始,此运算符已被弃用;预计在未来的 MySQL 版本中将不再支持。应用程序应调整为使用标准 SQL NOT 运算符。

  • AND, &&

    逻辑 AND。如果所有操作数均为非零且非NULL,则计算结果为1,如果一个或多个操作数为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
    

    && 运算符是 MySQL 的非标准扩展。从 MySQL 8.0.17 开始,此运算符已被弃用;预计在未来的 MySQL 版本中将不再支持。应用程序应调整为使用标准 SQL AND 运算符。

  • 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
    

    注意

    如果启用了 PIPES_AS_CONCAT SQL 模式,则 || 表示 SQL 标准的字符串连接运算符(类似于 CONCAT())。

    || 运算符是 MySQL 的非标准扩展。从 MySQL 8.0.17 开始,该运算符已被弃用;预计在未来的 MySQL 版本中将移除对其的支持。应用程序应调整为使用标准 SQL 的 OR 运算符。例外情况:如果启用了 PIPES_AS_CONCAT,则不适用弃用规则,因为在这种情况下,|| 表示字符串连接。

  • 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)

14.4.4 分配运算符

原文:dev.mysql.com/doc/refman/8.0/en/assignment-operators.html

表 14.6 分配运算符

名称描述
:=分配一个值
=分配一个值(作为SET语句的一部分,或作为UPDATE语句中的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 语句中使用:=运算符既可以设置变量的值又可以读取变量的值,但不建议这样做。第 11.4 节,“用户定义变量”解释了为什么应该避免这样做。

  • =

    此运算符用于在下面两种情况下执行值分配,分别在接下来的两段中描述。

    SET语句中,=被视为一个赋值运算符,导致操作符左侧的用户变量取得右侧的值。(换句话说,在SET语句中使用时,=:=的作用是相同的。)右侧的值可以是一个字面值,存储值的另一个变量,或者产生标量值的任何合法表达式,包括查询的结果(前提是这个值是一个标量值)。你可以在同一个SET语句中执行多个赋值操作。

    UPDATE语句的SET子句中,=也充当一个赋值运算符;然而,在这种情况下,它会导致操作符左侧命名的列取得右侧给定的值,前提是UPDATE中的任何WHERE条件都得到满足。你可以在同一个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
    

    欲了解更多信息,请参阅第 15.7.6.1 节,“变量赋值的 SET 语法”,第 15.2.17 节,“UPDATE 语句”,以及第 15.2.15 节,“子查询”。

14.5 流程控制函数

原文:dev.mysql.com/doc/refman/8.0/en/flow-control-functions.html

表 14.7 流程控制运算符

名称描述
CASECase 运算符
IF()如果/否则构造
IFNULL()如果/否则构造
NULLIF()如果expr1 = expr2则返回NULL
  • 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

    第一个CASE语法返回第一个*value=compare_value*为真的*result*。第二个语法返回第一个为真的条件的结果。如果没有比较或条件为真,则返回ELSE后的结果,如果没有ELSE部分则返回NULL

    注意

    此处描述的CASE 运算符的语法与第 15.6.5.1 节“CASE 语句”中描述的 SQL CASE 语句略有不同,用于存储程序内部。CASE语句不能有ELSE NULL子句,并以END CASE而不是END结束。

    CASE表达式的返回类型是所有结果值的聚合类型:

    • 如果所有类型都是数值型,则聚合类型也是数值型:

      • 如果至少有一个参数是双精度,则结果为双精度。

      • 否则,如果至少有一个参数是DECIMAL,则结果为DECIMAL

      • 否则,结果是整数类型(有一个例外):

        • 如果所有整数类型都是全部有符号或全部无符号,结果是相同符号且精度是所有指定整数类型中最高的(即TINYINTSMALLINTMEDIUMINTINTBIGINT)。

        • 如果有符号和无符号整数类型的组合,结果是有符号的,精度可能更高。例如,如果类型是有符号的INT和无符号的INT,结果是有符号的BIGINT

        • 例外情况是无符号的BIGINT与任何有符号整数类型相结合。结果是具有足够精度和标度为 0 的DECIMAL

    • 如果所有类型都是BIT,结果是BIT。否则,BIT参数被视为类似于BIGINT

    • 如果所有类型都是YEAR,结果是YEAR。否则,YEAR 参数被视为类似于INT

    • 如果所有类型都是字符字符串(CHARVARCHAR),结果是具有由操作数的最长字符长度确定的最大长度的VARCHAR

    • 如果所有类型都是字符或二进制字符串,结果是VARBINARY

    • SETENUM被视为类似于VARCHAR;结果是VARCHAR

    • 如果所有类型都是JSON,结果是JSON

    • 如果所有类型都是时间类型,结果就是时间类型:

      • 如果所有时间类型都是DATETIMETIMESTAMP,结果分别是DATETIMETIMESTAMP

      • 否则,对于时间类型的混合,结果是DATETIME

    • 如果所有类型都是GEOMETRY,结果就是GEOMETRY

    • 如果任何类型是BLOB,结果是BLOB

    • 对于所有其他类型组合,结果是VARCHAR

    • 对于类型聚合,字面NULL操作数将被忽略。

    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
    
  • IF(*expr1*,*expr2*,*expr3*)

    如果*expr1TRUE*expr1* <> 0*expr1* IS NOT NULL),IF()返回expr2。否则,返回expr3*。

    注意

    还有一个IF 语句,与此处描述的IF() 函数不同。请参见第 15.6.5.2 节,“IF 语句”。

    如果*expr2expr3*中只有一个明确为NULL,则IF()函数的结果类型是非NULL表达式的类型。

    IF()的默认返回类型(当它存储到临时表时可能很重要)计算如下:

    • 如果*expr2expr3*产生字符串,则结果是字符串。

      如果*expr2expr3*都是字符串,则结果是区分大小写的,如果任一字符串是区分大小写的。

    • 如果*expr2expr3*产生浮点值,则结果是浮点值。

    • 如果*expr2expr3*产生整数,则结果是整数。

    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'
    
  • IFNULL(*expr1*,*expr2*)

    如果*expr1不是NULLIFNULL()返回expr1;否则返回expr2*。

    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*)的默认返回类型是两个表达式中更“通用”的类型,按顺序为STRINGREALINTEGER。考虑基于表达式的表或 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*)

    如果*expr1* = *expr2*为真,则返回NULL,否则返回*expr1*。这与CASE WHEN *expr1* = *expr2* THEN NULL ELSE *expr1* END相同。

    返回值与第一个参数具有相同的类型。

    mysql> SELECT NULLIF(1,1);
     -> NULL
    mysql> SELECT NULLIF(1,2);
     -> 1
    

    注意

    MySQL 在参数不相等时会对*expr1*进行两次评估。

MySQL 8.0.22 中这些函数对系统变量值的处理发生了变化。对于这些函数中的每一个,如果第一个参数仅包含在第二个参数使用的字符集和校对规则中存在的字符(且它是常量),则后者的字符集和校对规则用于进行比较。在 MySQL 8.0.22 及更高版本中,系统变量值被处理为具有相同字符集和校对规则的列值。一些使用这些函数与系统变量的查询可能会被拒绝,出现 Illegal mix of collations。在这种情况下,您应该将系统变量转换为正确的字符集和校对规则。

14.6 数值函数和运算符

原文:dev.mysql.com/doc/refman/8.0/en/numeric-functions.html

14.6.1 算术运算符

14.6.2 数学函数

表格 14.8 数值函数和运算符

名称描述
%, MOD取模运算符
*乘法运算符
+加法运算符
-减法运算符
-改变参数的符号
/除法运算符
ABS()返回绝对值
ACOS()返回反余弦
ASIN()返回反正弦
ATAN()返回反正切
ATAN2(), ATAN()返回两个参数的反正切
CEIL()返回不小于参数的最小整数值
CEILING()返回不小于参数的最小整数值
CONV()在不同进制之间转换数字
COS()返回余弦值
COT()返回余切
CRC32()计算循环冗余校验值
DEGREES()将弧度转换为角度
DIV整数除法
EXP()指数运算
FLOOR()返回不大于参数的最大整数值
LN()返回参数的自然对数
LOG()返回第一个参数的自然对数
LOG10()返回参数的以 10 为底的对数
LOG2()返回参数的以 2 为底的对数
MOD()返回余数
PI()返回圆周率的值
POW()返回参数的指定幂值
POWER()返回参数的指定幂次方
RADIANS()返回转换为弧度的参数
RAND()返回一个随机浮点值
ROUND()四舍五入参数
SIGN()返回参数的符号
SIN()返回参数的正弦值
SQRT()返回参数的平方根
TAN()返回参数的正切值
TRUNCATE()截断到指定的小数位数
名称描述

14.6.1 算术运算符

原文:dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html

表 14.9 算术运算符

名称描述
%, MOD取模运算符
*乘法运算符
+加法运算符
-减法运算符
-改变参数的符号
/除法运算符
DIV整数除法

常见的算术运算符都是可用的。结果根据以下规则确定:

  • 对于-+*,如果两个操作数都是整数,则结果将以BIGINT(64 位)精度计算。

  • 如果两个操作数都是整数且其中任何一个是无符号的,则结果将是无符号整数。对于减法,如果启用了NO_UNSIGNED_SUBTRACTION SQL 模式,则结果将是有符号的,即使任何操作数是无符号的。

  • 如果+-/*%的任何操作数是实数或字符串值,则结果的精度为具有最大精度的操作数的精度。

  • 在使用/进行除法运算时,使用两个精确值操作数的结果的精度为第一个操作数的精度加上div_precision_increment系统变量的值(默认为 4)。例如,表达式5.05 / 0.014的结果具有六位小数的精度(360.714286)。

这些规则适用于每个操作,因此嵌套计算意味着每个组件的精度。因此,(14620 / 9432456) / (24250 / 9432456),首先解析为(0.0014) / (0.0026),最终结果具有 8 位小数的精度(0.60288653)。

由于这些规则及其应用方式,应注意确保计算的组件和子组件使用适当级别的精度。参见第 14.10 节,“转换函数和运算符”。

有关数值表达式计算中溢出处理的信息,请参见第 13.1.7 节,“超出范围和溢出处理”。

算术运算符适用于数字。对于其他类型的值,可能会提供替代操作。例如,要添加日期值,请使用DATE_ADD(); 请参阅第 14.7 节,“日期和时间函数”。

  • +

    加法:

    mysql> SELECT 3+5;
     -> 8
    
  • -

    减法:

    mysql> SELECT 3-5;
     -> -2
    
  • -

    一元负号。此运算符改变操作数的符号。

    mysql> SELECT - 2;
     -> -2
    

    注意

    如果此运算符与BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")一起使用,则返回值也是BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")。这意味着您应避免对可能具有值−2⁶³的整数使用-

  • *

    乘法:

    mysql> SELECT 3*5;
     -> 15
    mysql> SELECT 18014398509481984*18014398509481984.0;
     -> 324518553658426726783156020576256.0
    mysql> SELECT 18014398509481984*18014398509481984;
     -> out-of-range error
    

    最后一个表达式会产生错误,因为整数乘法的结果超出了BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")计算的 64 位范围。(请参阅第 13.1 节,“数值数据类型”。)

  • /

    除法:

    mysql> SELECT 3/5;
     -> 0.60
    

    除以零会产生NULL结果:

    mysql> SELECT 102/(1-1);
     -> NULL
    

    仅当在将其结果转换为整数的上下文中执行时,才使用BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")算术计算除法。

  • DIV

    整数除法。舍弃除法结果小数点右侧的任何小数部分。

    如果任一操作数具有非整数类型,则在将结果转换为BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")之前,将操作数转换为DECIMAL - DECIMAL, NUMERIC")并使用DECIMAL - DECIMAL, NUMERIC")算术进行除法。如果结果超出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*的余数。有关更多信息,请参见第 14.6.2 节,“数学函数”中MOD()函数的描述。

14.6.2 数学函数

原文:dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html

Table 14.10 数学函数

名称描述
ABS()返回绝对值
ACOS()返回反余弦值
ASIN()返回反正弦值
ATAN()返回反正切值
ATAN2(), ATAN()返回两个参数的反正切
CEIL()返回不小于参数的最小整数值
CEILING()返回不小于参数的最小整数值
CONV()在不同进制之间转换数字
COS()返回余弦值
COT()返回余切值
CRC32()计算循环冗余校验值
DEGREES()将弧度转换为角度
EXP()求幂
FLOOR()返回不大于参数的最大整数值
LN()返回参数的自然对数
LOG()返回第一个参数的自然对数
LOG10()返回参数的以 10 为底的对数
LOG2()返回参数的以 2 为底的对数
MOD()返回余数
PI()返回圆周率的值
POW()返回指定幂次的参数
POWER()返回指定幂次的参数
RADIANS()返回转换为弧度的参数
RAND()返回一个随机浮点值
ROUND()四舍五入参数
SIGN()返回参数的符号
SIN()返回参数的正弦值
SQRT()返回参数的平方根
TAN()返回参数的正切
TRUNCATE()截断到指定的小数位数
名称描述

所有数学函数在出现错误时返回NULL

  • ABS(*X*)

    返回*X的绝对值,如果X*为NULL,则返回NULL

    结果类型源自参数类型。这意味着ABS(-9223372036854775808)会产生错误,因为结果无法存储在有符号的BIGINT值中。

    mysql> SELECT ABS(2);
     -> 2
    mysql> SELECT ABS(-32);
     -> 32
    

    此函数可安全用于BIGINT值。

  • ACOS(*X*)

    返回*X的反余弦,即,其余弦值为X的值。如果X不在-11的范围内,或者X*为NULL,则返回NULL

    mysql> SELECT ACOS(1);
     -> 0
    mysql> SELECT ACOS(1.0001);
     -> NULL
    mysql> SELECT ACOS(0);
     -> 1.5707963267949
    
  • ASIN(*X*)

    返回*X的反正弦,即,其正弦值为X的值。如果X不在-11的范围内,或者X*为NULL,则返回NULL

    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的值。如果XNULL,则返回NULL*。

    mysql> SELECT ATAN(2);
     -> 1.1071487177941
    mysql> SELECT ATAN(-2);
     -> -1.1071487177941
    
  • ATAN(*Y*,*X*), ATAN2(*Y*,*X*)

    返回两个变量*XY的反正切。它类似于计算*Y* / *X*的反正切,只是使用两个参数的符号来确定结果的象限。如果XY*为NULL,则返回NULL

    mysql> SELECT ATAN(-2,2);
     -> -0.78539816339745
    mysql> SELECT ATAN2(PI(),0);
     -> 1.5707963267949
    
  • CEIL(*X*)

    CEIL()CEILING()的同义词。

  • CEILING(*X*)

    返回不小于*X的最小整数值。如果X*为NULL,则返回NULL

    mysql> SELECT CEILING(1.23);
     -> 2
    mysql> SELECT CEILING(-1.23);
     -> -1
    

    对于精确值数值参数,返回值具有精确值数值类型。对于字符串或浮点参数,返回值具有浮点类型。

  • CONV(*N*,*from_base*,*to_base*)

    在不同进制之间转换数字。返回从基数*from_base转换为基数to_base的数字N的字符串表示。如果任何参数为NULL,则返回NULL。参数N被解释为整数,但可以指定为整数或字符串。最小基数为2,最大基数为36。如果from_base是负数,则N被视为有符号数。否则,N*被视为无符号数。CONV()以 64 位精度工作。

    如果CONV()的任何参数为NULL,则返回NULL

    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以弧度给出。如果X*为NULL,则返回NULL

    mysql> SELECT COS(PI());
     -> -1
    
  • COT(*X*)

    返回*X的余切值。如果X*为NULL,则返回NULL

    mysql> SELECT COT(12);
     -> -1.5726734063977
    mysql> SELECT COT(0);
     -> out-of-range error
    
  • CRC32(*expr*)

    计算循环冗余校验值并返回一个 32 位无符号值。如果参数为NULL,则结果为NULL。预期参数为字符串,如果可能的话,如果参数不是字符串,则会被视为字符串。

    mysql> SELECT CRC32('MySQL');
     -> 3259397556
    mysql> SELECT CRC32('mysql');
     -> 2501908538
    
  • DEGREES(*X*)

    返回将弧度转换为度的参数*X。如果X*为NULL,则返回NULL

    mysql> SELECT DEGREES(PI());
     -> 180
    mysql> SELECT DEGREES(PI() / 2);
     -> 90
    
  • EXP(*X*)

    返回e(自然对数的底)的*X*次幂的值。该函数的反函数是LOG()(仅使用单个参数)或LN()

    如果*X*为NULL,此函数返回NULL

    mysql> SELECT EXP(2);
     -> 7.3890560989307
    mysql> SELECT EXP(-2);
     -> 0.13533528323661
    mysql> SELECT EXP(0);
     -> 1
    
  • FLOOR(*X*)

    返回不大于*X的最大整数值。如果X*为NULL,则返回NULL

    mysql> SELECT FLOOR(1.23), FLOOR(-1.23);
     -> 1, -2
    

    对于精确值数值参数,返回值具有精确值数值类型。对于字符串或浮点参数,返回值具有浮点类型。

  • FORMAT(*X*,*D*)

    将数字*X格式化为类似'#,###,###.##'的格式,四舍五入到D*位小数,并将结果作为字符串返回。有关详细信息,请参阅第 14.8 节“字符串函数和运算符”。

  • HEX(N_or_S)

    此函数可用于获取十进制数或字符串的十六进制表示;它的工作方式根据参数的类型而变化。有关详细信息,请参阅第 14.8 节“字符串函数和运算符”中此函数的描述。

  • LN(*X*)

    返回*X的自然对数;即X的以e为底的对数。如果X小于或等于 0.0E0,则函数返回NULL并报告警告“对数的参数无效”。如果X*为NULL,则返回NULL

    mysql> SELECT LN(2);
     -> 0.69314718055995
    mysql> SELECT LN(-2);
     -> NULL
    

    此函数与LOG(*X*)是同义词。该函数的反函数是EXP()函数。

  • LOG(*X*), LOG(*B*,*X*)

    如果使用一个参数调用此函数,则返回*X的自然对数。如果X小于或等于 0.0E0,则函数返回NULL并报告警告“对数的参数无效”。如果XB*为NULL,则返回NULL

    此函数的倒数(使用单个参数调用时)是EXP()函数。

    mysql> SELECT LOG(2);
     -> 0.69314718055995
    mysql> SELECT LOG(-2);
     -> NULL
    

    如果使用两个参数调用此函数,则返回以*B为底的X的对数。如果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并报告警告“对数的参数无效”。如果X*为NULL,则返回NULL

    mysql> SELECT LOG2(65536);
     -> 16
    mysql> SELECT LOG2(-100);
     -> NULL
    

    LOG2() 用于查找一个数字需要多少位来存储。此函数等同于表达式LOG(*X*) / LOG(2)

  • LOG10(*X*)

    返回*X的以 10 为底的对数。如果X小于或等于 0.0E0,则函数返回NULL并报告警告“对数的参数无效”。如果X*为NULL,则返回NULL

    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的余数。如果MN*为NULL,则返回NULL

    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 在内部使用完整的双精度值。

    因为此函数的返回值是双精度值,其精确表示可能因平台或实现而异。这也适用于使用PI()的任何表达式。参见第 13.1.4 节,“浮点类型(近似值) - FLOAT,DOUBLE”。

    mysql> SELECT PI();
     -> 3.141593
    mysql> SELECT PI()+0.000000000000000000;
     -> 3.141592653589793000
    
  • POW(*X*,*Y*)

    返回*XY次幂的值。如果XY*为NULL,则返回NULL

    mysql> SELECT POW(2,2);
     -> 4
    mysql> SELECT POW(2,-2);
     -> 0.25
    
  • POWER(*X*,*Y*)

    这是POW()的同义词。

  • RADIANS(*X*)

    返回将参数*X从度转换为弧度的值。(注意π弧度等于 180 度。)如果X*为NULL,则返回NULL

    mysql> SELECT RADIANS(90);
     -> 1.5707963267949
    
  • RAND([*N*])

    返回范围为0 <= v < 1.0的随机浮点值*v。要在范围i* <= R < j内获取随机整数R,可以使用表达式FLOOR(*i* + RAND() * (*j**i*))。例如,要在范围7 <= R < 12内获取随机整数,请使用以下语句:

    SELECT FLOOR(7 + (RAND() * 5));
    

    如果指定了整数参数*N*,则将其用作种子值:

    • 使用常量初始化参数时,种子在语句准备之前一次性初始化,然后执行。

    • 使用非常量初始化参数(例如列名),种子在每次调用RAND()时都会被初始化为该值。

    这种行为的一个含义是,对于相等的参数值,RAND(*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)
    

    WHERE子句中使用RAND()会为每一行(从一个表中选择)或每一行组合(从多个表连接中选择)评估。因此,对于优化器而言,RAND()不是一个常量值,不能用于索引优化。有关更多信息,请参见第 10.2.1.20 节,“函数调用优化”。

    ORDER BYGROUP BY子句中使用带有RAND()值的列可能会产生意外结果,因为对于任一子句,RAND()表达式可能会对同一行进行多次评估,每次返回不同的结果。如果目标是以随机顺序检索行,可以使用类似以下语句:

    SELECT * FROM *tbl_name* ORDER BY RAND();
    

    要从一组行中选择随机样本,请将ORDER BY RAND()LIMIT结合使用:

    SELECT * FROM table1, table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000;
    

    RAND()并不是一个完美的随机生成器。它是一种快速生成随机数的方式,可在相同的 MySQL 版本的不同平台之间移植。

    此函数对基于语句的复制不安全。如果在将binlog_format设置为STATEMENT时使用此函数,将记录警告。

  • ROUND(*X*), ROUND(*X*,*D*)

    将参数*X四舍五入到D位小数。舍入算法取决于X的数据类型。如果未指定,D默认为 0。D可以为负,使得值X小数点左边的D位变为零。D的最大绝对值为 30;超过 30(或-30)的任何数字将被截断。如果XD*为NULL,则函数返回NULL

    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
    mysql> SELECT ROUND(.12345678901234567890123456789012345, 35);
     -> 0.123456789012345678901234567890
    

    返回值与第一个参数的类型相同(假设它是整数、双精度或十进制)。这意味着对于整数参数,结果是一个整数(没有小数位):

    mysql> SELECT ROUND(150.000,2), ROUND(150,2);
    +------------------+--------------+
    | ROUND(150.000,2) | ROUND(150,2) |
    +------------------+--------------+
    |           150.00 |          150 |
    +------------------+--------------+
    

    ROUND()根据第一个参数的类型使用以下规则:

    • 对于精确值数字,ROUND()使用“远离零的一半”或“向最近整数四舍五入”的规则:具有小数部分为.5 或更大的值,如果为正则四舍五入到下一个整数,如果为负则四舍五入到下一个整数。(换句话说,它远离零。)具有小于.5 的小数部分的值,如果为正则向下舍入到下一个整数,如果为负则向上舍入到下一个整数。

    • 对于近似值数字,结果取决于 C 库。在许多系统上,这意味着ROUND()使用“四舍五入到最近偶数”的规则:具有恰好处于两个整数之间的小数部分的值将四舍五入为最接近的偶数。

    以下示例显示了精确值和近似值的舍入方式不同:

    mysql> SELECT ROUND(2.5), ROUND(25E-1);
    +------------+--------------+
    | ROUND(2.5) | ROUND(25E-1) |
    +------------+--------------+
    | 3          |            2 |
    +------------+--------------+
    

    有关更多信息,请参阅第 14.24 节,“精确数学”。

    在 MySQL 8.0.21 及更高版本中,ROUND()(以及TRUNCATE())返回的数据类型根据以下规则确定:

    • 当第一个参数是任何整数类型时,返回类型始终为BIGINT - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT")。

    • 当第一个参数是任何浮点类型或任何非数值类型时,返回类型始终为DOUBLE - FLOAT, DOUBLE")。

    • 当第一个参数是DECIMAL - DECIMAL, NUMERIC")值时,返回类型也是DECIMAL

    • 返回值的类型属性也从第一个参数复制,除非第二个参数是常量值时,此时为DECIMAL

      当所需小数位数少于参数的精度时,结果的精度和精度将相应调整。

      此外,对于ROUND()(但不适用于TRUNCATE()函数),精度会增加一位以适应增加有效数字的四舍五入。如果第二个参数为负数,则调整返回类型,使其精度为 0,具有相应的精度。例如,ROUND(99.999, 2)返回100.00—第一个参数为DECIMAL(5, 3),返回类型为DECIMAL(5, 2)

      如果第二个参数为负数,则返回类型的精度为 0,并具有相应的精度;ROUND(99.999, -1)返回100,即DECIMAL(3, 0)

  • SIGN(*X*)

    返回参数的符号为-101,取决于*X是负数、零还是正数。如果X*为NULL,则返回NULL

    mysql> SELECT SIGN(-32);
     -> -1
    mysql> SELECT SIGN(0);
     -> 0
    mysql> SELECT SIGN(234);
     -> 1
    
  • SIN(*X*)

    返回以弧度表示的*X的正弦值。如果X*为NULL,则返回NULL

    mysql> SELECT SIN(PI());
     -> 1.2246063538224e-16
    mysql> SELECT ROUND(SIN(PI()));
     -> 0
    
  • SQRT(*X*)

    返回非负数*X的平方根。如果X*为NULL,则函数返回NULL

    mysql> SELECT SQRT(4);
     -> 2
    mysql> SELECT SQRT(20);
     -> 4.4721359549996
    mysql> SELECT SQRT(-16);
     -> NULL
    
  • TAN(*X*)

    返回以弧度表示的*X的正切值。如果X*为NULL,则返回NULL

    mysql> SELECT TAN(PI());
     -> -1.2246063538224e-16
    mysql> SELECT TAN(PI()+1);
     -> 1.5574077246549
    
  • TRUNCATE(*X*,*D*)

    返回将*X截断为D位小数的数字。如果D0,则结果没有小数点或小数部分。D可以为负数,以使值X的小数点左边的D位变为零。如果XD*为NULL,则函数返回NULL

    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
    

    所有数字都向零舍入。

    在 MySQL 8.0.21 及更高版本中,TRUNCATE()返回的数据类型遵循确定ROUND()函数返回类型的相同规则;有关详细信息,请参阅ROUND()的描述。

14.7 日期和时间函数

原文:dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html

本节描述了用于操作时间值的函数。有关每种日期和时间类型的值范围以及可以指定值的有效格式的描述,请参见第 13.2 节,“日期和时间数据类型”。

表格 14.11 日期和时间函数

名称描述
ADDDATE()将时间值(间隔)添加到日期值
ADDTIME()添加时间
CONVERT_TZ()将一个时区转换为另一个时区
CURDATE()返回当前日期
CURRENT_DATE(), CURRENT_DATECURDATE()的同义词
CURRENT_TIME(), CURRENT_TIMECURTIME()的同义词
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMPNOW()的同义词
CURTIME()返回当前时间
DATE()提取日期或日期时间表达式的日期部分
DATE_ADD()将时间值(间隔)添加到日期值
DATE_FORMAT()格式化指定的日期
DATE_SUB()从日期中减去一个时间值(间隔)
DATEDIFF()计算两个日期之间的差值
DAY()DAYOFMONTH()的同义词
DAYNAME()返回星期几的名称
DAYOFMONTH()返回月份中的日期(0-31)
DAYOFWEEK()返回参数的星期索引
DAYOFYEAR()返回一年中的日期(1-366)
EXTRACT()提取日期的部分
FROM_DAYS()将天数转换为日期
FROM_UNIXTIME()将 Unix 时间戳格式化为日期
GET_FORMAT()返回日期格式字符串
HOUR()提取小时
LAST_DAY返回参数月份的最后一天
LOCALTIME(), LOCALTIMENOW()的同义词
LOCALTIMESTAMP, LOCALTIMESTAMP()NOW()的同义词
MAKEDATE()从年份和一年中的天数创建日期
MAKETIME()从小时、分钟、秒创建时间
MICROSECOND()返回参数的微秒
MINUTE()返回参数的分钟
MONTH()返回传递日期的月份
MONTHNAME()返回月份的名称
NOW()返回当前日期和时间
PERIOD_ADD()向年-月添加一个周期
PERIOD_DIFF()返回两个周期之间的月数
QUARTER()返回日期参数的季度
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()使用单个参数,此函数返回日期或日期时间表达式;使用两个参数,返回参数的总和
TIMESTAMPADD()向日期时间表达式添加一个间隔
TIMESTAMPDIFF()返回两个日期时间表达式的差异,使用指定的单位
TO_DAYS()返回转换为天数的日期参数
TO_SECONDS()返回自公元 0 年以来的秒数
UNIX_TIMESTAMP()返回 Unix 时间戳
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*;

查询还选择未来日期的行。

函数通常接受日期值,但会忽略时间部分。通常接受时间值的函数会接受日期时间值并忽略日期部分。

返回当前日期或时间的函数在每次查询执行开始时仅计算一次。这意味着在单个查询中多次引用诸如NOW()的函数总是产生相同的结果。(对于我们的目的,单个查询还包括对存储程序(存储过程、触发器或事件)的调用以及该程序调用的所有子程序。)这个原则也适用于CURDATE()CURTIME()UTC_DATE()UTC_TIME()UTC_TIMESTAMP()以及它们的任何同义词。

CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE()FROM_UNIXTIME()函数返回当前会话时区的值,该时区作为time_zone系统变量的会话值可用。此外,UNIX_TIMESTAMP()假定其参数是会话时区中的日期时间值。参见 Section 7.1.15, “MySQL Server Time Zone Support”。

一些日期函数可以与“零”日期或不完整日期一起使用,例如'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()函数值作为参数时,一些函数是严格的,并拒绝具有零天部分的不完整日期:CONVERT_TZ(), DATE_ADD(), DATE_SUB(), DAYOFYEAR(), TIMESTAMPDIFF(), TO_DAYS(), TO_SECONDS(), WEEK(), WEEKDAY(), WEEKOFYEAR(), YEARWEEK().

支持TIMEDATETIMETIMESTAMP值的分数秒,精度可达微秒。接受时间参数的函数接受具有分数秒的值。从时间函数返回的值包括适当的分数秒。

  • ADDDATE(*date*,INTERVAL *expr* *unit*), ADDDATE(*date*,*days*)

    当以第二个参数的INTERVAL形式调用时,ADDDATE()DATE_ADD()的同义词。相关函数SUBDATE()DATE_SUB()的同义词。有关INTERVAL *unit*参数的信息,请参见时间间隔。

    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'
    

    如果*datedays*为NULL,此函数返回NULL

  • ADDTIME(*expr1*,*expr2*)

    ADDTIME()将*expr2添加到expr1并返回结果。expr1是时间或日期时间表达式,expr2是时间表达式。如果expr1expr2*为NULL,则返回NULL

    从 MySQL 8.0.28 开始,此函数和SUBTIME()函数的返回类型如下确定:

    • 如果第一个参数是动态参数(例如在准备好的语句中),返回类型为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()将给定时区*from_tz的日期时间值dt转换为给定时区to_tz*的值并返回结果。时区的指定方式如第 7.1.15 节“MySQL 服务器时区支持”中所述。如果任何参数无效或任何参数为NULL,此函数返回NULL

    在 32 位平台上,此函数的支持值范围与TIMESTAMP类型相同(有关范围信息,请参见第 13.2.1 节“日期和时间数据类型语法”)。在 64 位平台上,从 MySQL 8.0.28 开始,最大支持值为'3001-01-18 23:59:59.999999' UTC。

    无论平台或 MySQL 版本如何,如果从*from_tz*转换为 UTC 时的值超出支持范围,则不进行转换。

    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/Amsterdam'之类的命名时区,必须正确设置时区表。有关说明,请参见第 7.1.15 节“MySQL 服务器时区支持”。

  • CURDATE()

    返回当前日期作为值,格式为'*YYYY-MM-DD*'或*YYYYMMDD*,取决于函数在字符串或数字上下文中的使用方式。

    mysql> SELECT CURDATE();
     -> '2008-06-13'
    mysql> SELECT CURDATE() + 0;
     -> 20080613
    
  • CURRENT_DATE, CURRENT_DATE()

    CURRENT_DATECURRENT_DATE()CURDATE()的同义词。

  • CURRENT_TIME, CURRENT_TIME([*fsp*])

    CURRENT_TIMECURRENT_TIME()CURTIME()的同义词。

  • CURRENT_TIMESTAMP, CURRENT_TIMESTAMP([*fsp*])

    CURRENT_TIMESTAMPCURRENT_TIMESTAMP()NOW()的同义词。

  • CURTIME([*fsp*])

    返回当前时间作为值,格式为*'hh:mm:ss'hhmmss*,取决于函数在字符串或数字上下文中的使用方式。该值以会话时区表示。

    如果给定*fsp*参数以指定从 0 到 6 的小数秒精度,则返回值包括相应数量的小数秒部分。

    mysql> SELECT CURTIME();
    +-----------+
    | CURTIME() |
    +-----------+
    | 19:25:37  |
    +-----------+
    
    mysql> SELECT CURTIME() + 0;
    +---------------+
    | CURTIME() + 0 |
    +---------------+
    |        192537 |
    +---------------+
    
    mysql> SELECT CURTIME(3);
    +--------------+
    | CURTIME(3)   |
    +--------------+
    | 19:25:37.840 |
    +--------------+
    
  • DATE(*expr*)

    提取日期或日期时间表达式*expr的日期部分。如果expr*为NULL,则返回NULL

    mysql> SELECT DATE('2003-12-31 01:02:03');
     -> '2003-12-31'
    
  • DATEDIFF(*expr1*,*expr2*)

    DATEDIFF() 返回*expr1expr2之间相差的天数值,以天数表示从一个日期到另一个日期。expr1expr2*是日期或日期时间表达式。计算中仅使用值的日期部分。

    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
    

    如果*expr1expr2*为NULL,此函数返回NULL

  • DATE_ADD(*date*,INTERVAL *expr* *unit*), DATE_SUB(*date*,INTERVAL *expr* *unit*)

    这些函数执行日期算术运算。*date参数指定起始日期或日期时间值。expr是指定要从起始日期中添加或减去的间隔值的表达式。expr被评估为字符串;它可以以-开头表示负间隔。unit*是指示应解释表达式的单位的关键字。

    有关时间间隔语法的更多信息,包括完整的*unit指定符列表,每个unit值的expr*参数的预期形式,以及在时间算术中操作数解释的规则,请参阅时间间隔。

    返回值取决于参数:

    • 如果*date*为NULL,函数将返回NULL

    • 如果*date*参数是DATE值,并且您的计算仅涉及YEARMONTHDAY部分(即没有时间部分),则返回DATE

    • MySQL 8.0.28 及更高版本:)如果*date*参数是TIME值,并且计算仅涉及HOURSMINUTESSECONDS部分(即没有日期部分),则返回TIME

    • 如果第一个参数是DATETIME(或TIMESTAMP)值,或者第一个参数是DATE且*unit值使用HOURSMINUTESSECONDS,或者第一个参数是TIMEunit*值使用YEARMONTHDAY,则返回DATETIME

    • MySQL 8.0.28 及更高版本:)如果第一个参数是动态参数(例如,准备语句的参数),且第二个参数是仅包含YEARMONTHDAY值组合的间隔,则其解析类型为DATE;否则,其类型为DATETIME

    • 否则为字符串(类型VARCHAR)。

    注意

    在 MySQL 8.0.22 至 8.0.27 中,在准备语句中使用时,这些函数无论参数类型如何都返回DATETIME值。(Bug #103781)

    为了确保结果是DATETIME,您可以使用CAST()将第一个参数转换为DATETIME

    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'
    

    当向DATEDATETIME值添加MONTH间隔时,并且结果日期包含给定月份中不存在的日期时,日期将调整为该月的最后一天,如下所示:

    mysql> SELECT DATE_ADD('2024-03-30', INTERVAL 1 MONTH) AS d1, 
         >        DATE_ADD('2024-03-31', INTERVAL 1 MONTH) AS d2;
    +------------+------------+
    | d1         | d2         |
    +------------+------------+
    | 2024-04-30 | 2024-04-30 |
    +------------+------------+
    1 row in set (0.00 sec)
    
  • DATE_FORMAT(*date*,*format*)

    根据*format字符串格式化date*值。如果任一参数为NULL,函数将返回NULL

    下表中显示的指示符可用于 format 字符串。在格式指示符字符之前需要 % 字符。这些指示符也适用于其他函数:STR_TO_DATE(), TIME_FORMAT(), UNIX_TIMESTAMP()

    指示符描述
    %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月份名称 (January..December)
    %m月份,数字 (00..12)
    %pAMPM
    %r时间,12 小时制 (hh:mm:ss 后跟 AMPM)
    %S秒数 (00..59)
    %s秒数 (00..59)
    %T时间,24 小时制 (hh:mm:ss)
    %U周数 (00..53), 星期日为一周的第一天; WEEK() 模式 0
    %u周数 (00..53), 星期一为一周的第一天; WEEK() 模式 1
    %V周数 (01..53), 星期日为一周的第一天; WEEK() 模式 2; 与 %X 一起使用
    %v周数 (01..53), 星期一为一周的第一天; WEEK() 模式 3; 与 %x 一起使用
    %W星期名称 (Sunday..Saturday)
    %w星期几 (0=星期日..6=星期六)
    %X一周的年份,星期日为一周的第一天,数字,四位数; 与 %V 一起使用
    %x一周的年份,星期一为一周的第一天,数字,四位数; 与 %v 一起使用
    %Y年份,数字,四位数
    %y年份,数字 (两位数)
    %%一个字面上的 % 字符
    %*x*x,对于上面未列出的任何“x
    指示符描述

    月份和日期指示符的范围从零开始,因为 MySQL 允许存储不完整的日期,如 '2014-00-00'

    用于日期和月份名称和缩写的语言由 lc_time_names 系统变量的值控制(第 12.16 节,“MySQL 服务器区域设置支持”)。

    对于%U%u%V%v格式说明符,请参阅WEEK()函数的描述,了解有关模式值的信息。模式影响周编号的方式。

    DATE_FORMAT()返回一个字符串,其中包含由character_set_connectioncollation_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系统变量的值控制(参见第 12.16 节,“MySQL 服务器区域设置支持”)。如果date*为NULL,则返回NULL

    mysql> SELECT DAYNAME('2007-02-03');
     -> 'Saturday'
    
  • DAYOFMONTH(*date*)

    返回*date的月份中的日期,范围为131,对于日期如'0000-00-00''2008-00-00'等具有零日期部分的日期,返回0。如果date*为NULL,则返回NULL

    mysql> SELECT DAYOFMONTH('2007-02-03');
     -> 3
    
  • DAYOFWEEK(*date*)

    返回*date的星期索引(1 = 星期日,2 = 星期一,...,7 = 星期六)。这些索引值对应于 ODBC 标准。如果date*为NULL,则返回NULL

    mysql> SELECT DAYOFWEEK('2007-02-03');
     -> 7
    
  • DAYOFYEAR(*date*)

    返回*date的一年中的日期,范围为1366。如果date*为NULL,则返回NULL

    mysql> SELECT DAYOFYEAR('2007-02-03');
     -> 34
    
  • EXTRACT(*unit* FROM *date*)

    EXTRACT()函数使用与DATE_ADD()DATE_SUB()相同类型的*unit说明符,但是从日期中提取部分而不是执行日期算数。有关unit参数的信息,请参阅时间间隔。如果date*为NULL,则返回NULL

    mysql> SELECT EXTRACT(YEAR FROM '2019-07-02');
     -> 2019
    mysql> SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');
     -> 201907
    mysql> SELECT EXTRACT(DAY_MINUTE FROM '2019-07-02 01:02:03');
     -> 20102
    mysql> SELECT EXTRACT(MICROSECOND
     ->                FROM '2003-01-02 10:30:00.000123');
     -> 123
    
  • FROM_DAYS(*N*)

    给定一个日期数*N,返回一个DATE值。如果N*为NULL,则返回NULL

    mysql> SELECT FROM_DAYS(730669);
     -> '2000-07-03'
    

    谨慎使用FROM_DAYS()处理旧日期。它不适用于格里高利历(1582 年之前)之前的值。请参阅第 13.2.7 节,“MySQL 使用的日历是什么?”。

  • FROM_UNIXTIME(*unix_timestamp*[,*format*])

    unix_timestamp 表示为日期时间或字符字符串值。返回的值使用会话时区表示。(客户端可以设置会话时区,如第 7.1.15 节,“MySQL 服务器时区支持”中所述。)unix_timestamp 是一个内部时间戳值,表示自 '1970-01-01 00:00:00' UTC 以来的秒数,例如UNIX_TIMESTAMP()函数生成的值。

    如果省略 format,此函数将返回一个DATETIME值。

    如果 unix_timestampformatNULL,此函数将返回 NULL

    如果 unix_timestamp 是整数,则 DATETIME 的小数秒精度为零。当 unix_timestamp 是十进制值时,DATETIME 的小数秒精度与十进制值的精度相同,最多为 6。当 unix_timestamp 是浮点数时,日期时间的小数秒精度为 6。

    在 32 位平台上,unix_timestamp 的最大有用值为 2147483647.999999,返回 '2038-01-19 03:14:07.999999' UTC。在运行 MySQL 8.0.28 或更高版本的 64 位平台上,有效最大值为 32536771199.999999,返回 '3001-01-18 23:59:59.999999' UTC。无论平台或版本如何,unix_timestamp 的值大于有效最大值都将返回 0

    format 用于以与DATE_FORMAT()函数使用的格式字符串相同的方式格式化结果。如果提供了 format,则返回的值是一个VARCHAR

    mysql> SELECT FROM_UNIXTIME(1447430881);
     -> '2015-11-13 10:08:01'
    mysql> SELECT FROM_UNIXTIME(1447430881) + 0;
     -> 20151113100801
    mysql> SELECT FROM_UNIXTIME(1447430881,
     ->                      '%Y %D %M %h:%i:%s %x');
     -> '2015 13th November 10:08:01 2015'
    

    注意

    如果您使用UNIX_TIMESTAMP()FROM_UNIXTIME()在非 UTC 时区和 Unix 时间戳值之间进行转换,转换是有损的,因为映射在两个方向上不是一对一的。有关详细信息,请参阅UNIX_TIMESTAMP()函数的描述。

  • GET_FORMAT({DATE|TIME|DATETIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})

    返回一个格式字符串。此函数与DATE_FORMAT()STR_TO_DATE()函数结合使用时很有用。

    如果*format*为NULL,则此函数返回NULL

    第一个和第二个参数的可能值会导致多个可能的格式字符串(有关使用的占位符,请参见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的小时。对于一天中的时间值,返回值的范围是023。但是,TIME值的范围实际上要大得多,因此HOUR可能返回大于23的值。如果time*为NULL,则返回NULL

    mysql> SELECT HOUR('10:05:03');
     -> 10
    mysql> SELECT HOUR('272:59:59');
     -> 272
    
  • LAST_DAY(*date*)

    获取一个日期或日期时间值,并返回该月的最后一天的相应值。如果参数无效或为NULL,则返回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*])

    LOCALTIMELOCALTIME()NOW() 的同义词。

  • LOCALTIMESTAMP, LOCALTIMESTAMP([*fsp*])

    LOCALTIMESTAMPLOCALTIMESTAMP()NOW() 的同义词。

  • MAKEDATE(*year*,*dayofyear*)

    返回一个日期,给定年份和一年中的天数。dayofyear 必须大于 0,否则结果为NULL。如果任一参数为NULL,结果也为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*)

    返回从*hourminutesecond*参数计算的时间值。如果任一参数为NULL,则返回NULL

    second 参数可以有小数部分。

    mysql> SELECT MAKETIME(12,15,30);
     -> '12:15:30'
    
  • MICROSECOND(*expr*)

    返回从时间或日期时间表达式*expr中计算的微秒,范围从0999999的数字。如果expr*为NULL,则返回NULL

    mysql> SELECT MICROSECOND('12:00:00.123456');
     -> 123456
    mysql> SELECT MICROSECOND('2019-12-31 23:59:59.000010');
     -> 10
    
  • MINUTE(*time*)

    返回*time的分钟,范围为059,如果time*为NULL,则返回NULL

    mysql> SELECT MINUTE('2008-02-03 10:05:03');
     -> 5
    
  • MONTH(*date*)

    返回*date的月份,对于一月到十二月的范围为112,对于具有零月部分的日期(如'0000-00-00''2008-00-00')为0。如果date*为NULL,则返回NULL

    mysql> SELECT MONTH('2008-02-03');
     -> 2
    
  • MONTHNAME(*date*)

    返回*date的月份的全名。名称的语言由lc_time_names系统变量的值控制(第 12.16 节,“MySQL 服务器区域设置支持”)。如果date*为NULL,则返回NULL

    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()的返回值。这意味着二进制日志中的时间戳设置不会影响对SYSDATE()的调用。将时间戳设置为非零值会导致每次后续调用NOW()都返回该值。将时间戳设置为零会取消此效果,使得NOW()再次返回当前日期和时间。

    有关这两个函数之间的差异的更多信息,请参阅SYSDATE()的描述。

  • PERIOD_ADD(*P*,*N*)

    将*N个月添加到格式为YYMMYYYYMM的期间P中。返回格式为YYYYMM*的值。

    注意

    期间参数*P*不是日期值。

    如果*PN*为NULL,则此函数返回NULL

    mysql> SELECT PERIOD_ADD(200801,2);
     -> 200803
    
  • PERIOD_DIFF(*P1*,*P2*)

    返回期间*P1P2之间的月份数。P1P2应该是格式为YYMMYYYYMM的值。请注意,期间参数P1P2*不是日期值。

    如果*P1P2*为NULL,则此函数返回NULL

    mysql> SELECT PERIOD_DIFF(200802,200703);
     -> 11
    
  • QUARTER(*date*)

    返回*date的年份季度,范围为14,如果date*为NULL则返回NULL

    mysql> SELECT QUARTER('2008-04-01');
     -> 2
    
  • SECOND(*time*)

    返回*time的秒数,范围为059,如果time*为NULL则返回NULL

    mysql> SELECT SECOND('10:05:03');
     -> 3
    
  • SEC_TO_TIME(*seconds*)

    返回*seconds*参数转换为小时、分钟和秒的TIME值。结果的范围受限于TIME数据类型的范围。如果参数对应的值超出该范围,则会发出警告。

    如果*seconds*为NULL,则函数返回NULL

    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 值,如果字符串仅包含日期或时间部分,则返回一个DATETIME 值。如果strformatNULL,则函数返回NULL。如果从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'
    

    日期值的部分的范围检查如第 13.2.2 节,“日期、日期时间和时间戳类型”中所述。这意味着,例如,“零”日期或部分值为 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'
    

    如果启用了NO_ZERO_DATE SQL 模式,则不允许零日期。在这种情况下,STR_TO_DATE() 返回NULL并生成警告:

    mysql> SET sql_mode = '';
    mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
    +---------------------------------------+
    | STR_TO_DATE('00/00/0000', '%m/%d/%Y') |
    +---------------------------------------+
    | 0000-00-00                            |
    +---------------------------------------+
    mysql> SET sql_mode = 'NO_ZERO_DATE';
    mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
    +---------------------------------------+
    | STR_TO_DATE('00/00/0000', '%m/%d/%Y') |
    +---------------------------------------+
    | NULL                                  |
    +---------------------------------------+
    mysql> SHOW WARNINGS\G
    *************************** 1\. row ***************************
      Level: Warning
       Code: 1411
    Message: Incorrect datetime value: '00/00/0000' for function str_to_date
    

    在 MySQL 8.0.35 之前,可以将无效的日期字符串(例如 '2021-11-31')传递给此函数。在 MySQL 8.0.35 及更高版本中,STR_TO_DATE() 执行完整的范围检查,并在转换后的日期无效时引发错误。

    注意

    你不能使用格式"%X%V"将年周字符串转换为日期,因为如果周跨越月边界,则年和周的组合不能唯一标识年和月。要将年周转换为日期,还应指定星期几:

    mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
     -> '2004-10-18'
    

    您还应该注意,对于日期和日期时间值的日期部分,STR_TO_DATE()仅检查年、月和日的有效性。更准确地说,这意味着检查年份以确保它在 0-9999 的范围内,检查月份以确保它在 1-12 的范围内,检查日期以确保它在 1-31 的范围内,但服务器不会检查这些值的组合。例如,SELECT STR_TO_DATE('23-2-31', '%Y-%m-%d')返回2023-02-31。启用或禁用ALLOW_INVALID_DATES服务器 SQL 模式对此行为没有影响。有关更多信息,请参阅第 13.2.2 节,“DATE、DATETIME 和 TIMESTAMP 类型”。

  • SUBDATE(*date*,INTERVAL *expr* *unit*)SUBDATE(*expr*,*days*)

    当使用第二个参数的INTERVAL形式调用时,SUBDATE()DATE_SUB()的同义词。有关INTERVAL *unit*参数的信息,请参阅DATE_ADD()的讨论。

    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。在这种情况下,它被解释为要从日期或日期时间表达式expr*中减去的天数。

    mysql> SELECT SUBDATE('2008-01-02 12:00:00', 31);
     -> '2007-12-02 12:00:00'
    

    如果任何参数为NULL,则此函数返回NULL

  • SUBTIME(*expr1*,*expr2*)

    SUBTIME()返回*expr1* − expr2,以与*expr1相同格式的值表示。expr1是时间或日期时间表达式,expr2*是时间表达式。

    此函数返回类型的分辨率与ADDTIME()函数的执行方式相同;有关更多信息,请参阅该函数的描述。

    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'
    

    如果*expr1expr2*为NULL,则此函数返回NULL

  • 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()返回的值。这意味着二进制日志中的时间戳设置对SYSDATE()的调用没有影响。

    因为SYSDATE()甚至在同一语句中可能返回不同的值,并且不受SET TIMESTAMP的影响,因此它是不确定的,因此在使用基于语句的二进制日志记录时不安全。如果这是一个问题,您可以使用基于行的日志记录。

    或者,您可以使用--sysdate-is-now选项,使SYSDATE()成为NOW()的别名。如果在复制源服务器和副本上都使用该选项,则有效。

    SYSDATE()的不确定性特性也意味着无法使用索引来评估引用它的表达式。

  • TIME(*expr*)

    提取时间或日期时间表达式*expr的时间部分,并将其作为字符串返回。如果expr*为NULL,则返回NULL

    此函数对基于语句的复制不安全。如果在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表示为时间值。expr1expr2是转换为TIMEDATETIME表达式的字符串;在转换后,它们必须是相同类型的。如果expr1expr2*为NULL,则返回NULL

    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作为日期时间值返回。使用两个参数时,它将时间表达式expr2添加到日期或日期时间表达式expr1中,并将结果作为日期时间值返回。如果exprexpr1expr2*为NULL,则返回NULL

    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添加到日期或日期时间表达式datetime_expr中。interval的单位由unit*参数给出,应为以下值之一:MICROSECOND(微秒)、SECONDMINUTEHOURDAYWEEKMONTHQUARTERYEAR

    *unit*值可以使用如下所示的关键字之一指定,也可以使用SQL_TSI_前缀。例如,DAYSQL_TSI_DAY都是合法的。

    如果*intervaldatetime_expr*为NULL,则此函数返回NULL

    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'
    

    当向DATEDATETIME值添加MONTH间隔时,如果结果日期包含给定月份中不存在的日期,则将日期调整为该月的最后一天,如下所示:

    mysql> SELECT TIMESTAMPADD(MONTH, 1, DATE '2024-03-30') AS t1, 
         >        TIMESTAMPADD(MONTH, 1, DATE '2024-03-31') AS t2;
    +------------+------------+
    | t1         | t2         |
    +------------+------------+
    | 2024-04-30 | 2024-04-30 |
    +------------+------------+
    1 row in set (0.00 sec)
    
  • TIMESTAMPDIFF(*unit*,*datetime_expr1*,*datetime_expr2*)

    返回*datetime_expr2* − datetime_expr1,其中*datetime_expr1datetime_expr2是日期或日期时间表达式。一个表达式可以是日期,另一个可以是日期时间;日期值在必要时被视为具有时间部分'00:00:00'的日期时间。结果(整数)的单位由unit参数给出。unit*的合法值与TIMESTAMPADD()函数的描述中列出的相同。

    如果*datetime_expr1datetime_expr2*为NULL,则此函数返回NULL

    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
    

    注意

    该函数的日期或日期时间参数的顺序与使用 2 个参数调用TIMESTAMP()函数时相反。

  • TIME_FORMAT(*time*,*format*)

    这类似于DATE_FORMAT()函数,但*format字符串可能仅包含有关小时、分钟、秒和微秒的格式说明符。其他说明符会产生NULL0。如果timeformat*为NULL,则TIME_FORMAT()返回NULL

    如果*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参数转换为秒的结果。如果time*为NULL,则返回NULL

    mysql> SELECT TIME_TO_SEC('22:23:00');
     -> 80580
    mysql> SELECT TIME_TO_SEC('00:39:38');
     -> 2378
    
  • TO_DAYS(*date*)

    给定一个日期*date,返回一个日期编号(自公元 0 年以来的天数)。如果date*为NULL,则返回NULL

    mysql> SELECT TO_DAYS(950501);
     -> 728779
    mysql> SELECT TO_DAYS('2007-10-07');
     -> 733321
    

    TO_DAYS()不适用于格里高利历(1582 年)出现之前的值,因为它没有考虑到在日历更改时丢失的天数。对于 1582 年之前的日期(可能是其他地区的较晚年份),此函数的结果不可靠。有关详细信息,请参阅第 13.2.7 节,“MySQL 使用的日历是什么?”。

    请记住,MySQL 将日期中的两位年份值转换为四位形式,使用的规则在第 13.2 节,“日期和时间数据类型”中。例如,'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)
    

    无论是否启用ALLOW_INVALID_DATES SQL 服务器模式,这都是正确的。

  • TO_SECONDS(*expr*)

    给定一个日期或日期时间*expr,返回自公元 0 年以来的秒数。如果expr*不是有效的日期或日期时间值(包括NULL),则返回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.2.7 节,“MySQL 使用的日历是什么?”。

    TO_DAYS()一样,TO_SECONDS(),将日期中的两位年份值转换为四位形式,使用的规则在第 13.2 节,“日期和时间数据类型”中。

    在 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)
    

    无论是否启用ALLOW_INVALID_DATES SQL 服务器模式,这都是正确的。

  • UNIX_TIMESTAMP([*date*])

    如果调用UNIX_TIMESTAMP()时没有*date*参数,它将返回一个表示自'1970-01-01 00:00:00' UTC 以来的秒数的 Unix 时间戳。

    如果使用*date参数调用UNIX_TIMESTAMP(),它将返回自'1970-01-01 00:00:00' UTC 以来的秒数值。服务器将date解释为会话时区中的值,并将其转换为 UTC 中的内部 Unix 时间戳值。(客户端可以根据第 7.1.15 节“MySQL 服务器时区支持”中的描述设置会话时区。)date参数可以是DATEDATETIMETIMESTAMP字符串,或以YYMMDDYYMMDDhhmmssYYYYMMDDYYYYMMDDhhmmss*格式的数字。如果参数包括时间部分,则可以选择包括小数秒部分。

    如果没有给定参数或参数不包括小数秒部分,则返回值为整数,或者给定包括小数秒部分的参数,则返回DECIMAL

    当*date*参数是TIMESTAMP列时,UNIX_TIMESTAMP()直接返回内部时间戳值,没有隐式的“字符串到 Unix 时间戳”的转换。

    在 MySQL 8.0.28 之前,参数值的有效范围与TIMESTAMP数据类型相同:'1970-01-01 00:00:01.000000' UTC 到'2038-01-19 03:14:07.999999' UTC。对于运行在 64 位平台上的 MySQL 8.0.28 及更高版本,UNIX_TIMESTAMP()的参数值的有效范围为'1970-01-01 00:00:01.000000' UTC 到'3001-01-19 03:14:07.999999' UTC(对应 32536771199.999999 秒)。

    无论 MySQL 版本或平台架构如何,如果将超出范围的日期传递给UNIX_TIMESTAMP(),它将返回0。如果*date*为NULL,则返回NULL

    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()FROM_UNIXTIME()在非协调世界时时区和 Unix 时间戳值之间进行转换,转换是有损的,因为映射在两个方向上不是一对一的。例如,由于夏令时等本地时区更改的惯例,可能导致UNIX_TIMESTAMP()将两个在非协调世界时时区中不同的值映射到相同的 Unix 时间戳值。FROM_UNIXTIME()将该值映射回原始值中的一个。以下是一个示例,使用在MET时区中不同的值:

    mysql> SET time_zone = 'MET';
    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       |
    +---------------------------+
    

    注意

    要使用诸如'MET''Europe/Amsterdam'之类的命名时区,必须正确设置时区表。有关说明,请参见第 7.1.15 节,“MySQL 服务器时区支持”。

    如果要减去UNIX_TIMESTAMP()列,可能需要将它们转换为有符号整数。参见第 14.10 节,“转换函数和运算符”。

  • UTC_DATEUTC_DATE()

    返回当前的协调世界时日期作为一个值,格式为'*YYYY-MM-DD*'或*YYYYMMDD*,取决于函数在字符串或数字上下文中的使用方式。

    mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
     -> '2003-08-14', 20030814
    
  • UTC_TIMEUTC_TIME([*fsp*])

    返回当前的协调世界时时间作为一个值,格式为*'hh:mm:ss'hhmmss*,取决于函数在字符串或数字上下文中的使用方式。

    如果给定*fsp*参数以指定从 0 到 6 的小数秒精度,则返回值包括相应数量的小数秒部分。

    mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
     -> '18:07:53', 180753.000000
    
  • UTC_TIMESTAMPUTC_TIMESTAMP([*fsp*])

    返回当前的协调世界时日期和时间作为一个值,格式为'*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()的两参数形式使您能够指定周从星期日或星期一开始,返回值应该在053153的范围内。如果省略mode*参数,则使用default_week_format系统变量的值。请参见第 7.1.8 节,“服务器系统变量”。对于NULL日期值,函数返回NULL

    以下表描述了*mode*参数的工作方式。

    模式一周的第一天范围第 1 周是第一周 …
    0星期日0-53今年有一个星期日
    1星期一0-53今年有 4 天或更多天
    2星期日1-53今年有一个星期日
    3星期一1-53今年有 4 天或更多天
    4星期日0-53今年有 4 天或更多天
    5星期一0-53今年有一个星期一
    6星期日1-53今年有 4 天或更多天
    7星期一1-53今年有一个星期一

    对于具有“今年有 4 天或更多天”的*mode*值,周数按照 ISO 8601:1988 编号:

    • 如果包含 1 月 1 日的那一周有 4 天或更多天,那么它就是第 1 周。

    • 否则,它就是上一年的最后一周,下一周就是第 1 周。

    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
    

    如果一个日期落在上一年的最后一周,且您没有使用2367作为可选的*mode*参数,则 MySQL 将返回0

    mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
     -> 2000, 0
    

    有人可能会认为WEEK()应该返回52,因为给定的日期实际上出现在 1999 年的第 52 周。但WEEK()返回0,以便返回值是“给定年份中的周数”。这使得当与从日期中提取日期部分的其他函数结合使用时,WEEK()函数是可靠的。

    如果您希望结果相对于包含给定日期的一周的第一天的年份进行评估,请使用0257作为可选的*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 = 星期一,1 = 星期二,… 6 = 星期日)。如果date*为NULL,则返回NULL

    mysql> SELECT WEEKDAY('2008-02-03 22:23:00');
     -> 6
    mysql> SELECT WEEKDAY('2007-11-06');
     -> 1
    
  • WEEKOFYEAR(*date*)

    返回日期的日历周作为范围从153的数字。如果*date*为NULL,则返回NULL

    WEEKOFYEAR()是一个兼容函数,等效于WEEK(*date*,3)

    mysql> SELECT WEEKOFYEAR('2008-02-20');
     -> 8
    
  • YEAR(*date*)

    返回 date 的年份,范围为 10009999,或者对于“零”日期为 0。如果 dateNULL,则返回 NULL

    mysql> SELECT YEAR('1987-01-01');
     -> 1987
    
  • YEARWEEK(*date*), YEARWEEK(*date*,*mode*)

    返回日期的年份和周数。结果中的年份可能与年份参数中的年份在一年中的第一周和最后一周不同。如果 dateNULL,则返回 NULL

    mode 参数的工作方式与 WEEK() 函数的 mode 参数完全相同。对于单参数语法,使用 mode 值为 0。与 WEEK() 不同,default_week_format 的值不会影响 YEARWEEK()

    mysql> SELECT YEARWEEK('1987-01-01');
     -> 198652
    

    周数与 WEEK() 函数对可选参数 01 返回的周数 (0) 不同,因为 WEEK() 然后返回给定年份上下文中的周数。