表示临时值的日期和时间数据类型是 DATE
、 TIME
、 DATETIME
、 TIMESTAMP
和 YEAR
。
对于 DATE
和 DATETIME
范围描述, “支持的” 表示虽然早期的值可能有效,但没有保证。
MySQL 允许 TIME
、 DATETIME
和 TIMESTAMP
值具有微秒(6 位数字)精度。要定义包含小数秒部分的列,请使用语法
,其中 type_name
(fsp
)type_name
是 TIME
、 DATETIME
或 TIMESTAMP
,而 fsp
是小数秒精度。例如:
CREATE TABLE t1 (t TIME(3), dt DATETIME(6), ts TIMESTAMP(0));
如果给定,fsp
值必须在 0 到 6 之间。如果省略,默认精度为 0。(这与标准 SQL 的默认值 6 不同,以便与之前的 MySQL 版本兼容。)
任何 TIMESTAMP
或 DATETIME
列在表中可以具有自动初始化和更新属性;见 第 13.2.5 节,“自动初始化和更新 TIMESTAMP 和 DATETIME”。
-
一个日期。支持的范围是
'1000-01-01'
到'9999-12-31'
。MySQL 以'
格式显示YYYY-MM-DD
'DATE
值,但允许使用字符串或数字分配值到DATE
列。 -
日期和时间组合。支持的范围是
'1000-01-01 00:00:00.000000'
到'9999-12-31 23:59:59.499999'
。MySQL 以'
格式显示YYYY-MM-DD hh:mm:ss
[.fraction
]'DATETIME
值,但允许使用字符串或数字分配值到DATETIME
列。可选的
fsp
值在 0 到 6 之间,可以指定小数秒精度。值为 0 表示没有小数部分。如果省略,默认精度为 0。可以使用
DEFAULT
和ON UPDATE
列定义子句指定DATETIME
列的自动初始化和更新,如 第 13.2.5 节,“自动初始化和更新 TIMESTAMP 和 DATETIME” 所述。 -
一个时间戳。范围是
'1970-01-01 00:00:01.000000'
UTC 到'2038-01-19 03:14:07.499999'
UTC。时间戳
值存储为从纪元('1970-01-01 00:00:00'
UTC)以来的秒数。一个时间戳
不能表示值'1970-01-01 00:00:00'
,因为那相当于从纪元以来的 0 秒,而值 0 是保留用于表示'0000-00-00 00:00:00'
,“零”时间戳
值。可选的
fsp
值在 0 到 6 之间,可以指定小数秒精度。值 0 表示没有小数部分。如果省略,默认精度为 0。服务器处理
时间戳
定义取决于explicit_defaults_for_timestamp
系统变量的值(见 第 7.1.8 节,“服务器系统变量”)。如果
explicit_defaults_for_timestamp
启用,那么不会自动分配DEFAULT CURRENT_TIMESTAMP
或ON UPDATE CURRENT_TIMESTAMP
属性到任何时间戳
列。它们必须在列定义中明确包含。此外,任何时间戳
未明确声明为NOT NULL
都允许NULL
值。如果
explicit_defaults_for_timestamp
禁用,服务器将按照以下方式处理时间戳
:除非另有指定,否则表中的第一个
时间戳
列将自动设置为最近修改的日期和时间,如果没有明确分配值。这使得时间戳
对于记录INSERT
或UPDATE
操作的时间戳非常有用。你也可以通过将其设置为NULL
值来将任何时间戳
列设置为当前日期和时间,除非它被定义为允许NULL
值。自动初始化和更新到当前日期和时间可以使用
DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
列定义子句。默认情况下,第一个时间戳
列具有这些属性,如前所述。但是,任何时间戳
列都可以定义为具有这些属性。 -
一个时间。范围是
'-838:59:59.000000'
到'838:59:59.000000'
。MySQL 以'
格式显示hh:mm:ss
[.fraction
]'时间
值,但允许使用字符串或数字分配值到时间
列。可选的
fsp
值在 0 到 6 之间,可以指定小数秒精度。值为 0 表示没有小数部分。如果省略,默认精度为 0。 -
四位数字格式的一年。MySQL 以
YEAR
值的YYYY
格式显示,但允许使用字符串或数字分配值给YEAR
列。值显示为1901
到2155
,或0000
。有关
YEAR
显示格式和输入值的解释,请参阅 第 13.2.4 节,“YEAR 类型”。
聚合函数 SUM()
和 AVG()
不适用于时间值。(它们将值转换为数字,丢失第一个非数字字符后的所有内容。)要解决这个问题,请将其转换为数字单位,执行聚合操作,然后将其转换回时间值。示例:
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROM tbl_name;
SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROM tbl_name;