SQL 日期和时间函数
第 3.4 课 · 阅读时间:约 8 分钟 · 练习题 ↓
SQL 日期和时间函数可以返回当前日期、提取日期的各个部分、加减时间间隔、计算两个日期之间的差值,以及格式化日期以便输出。在本课中,你将通过 Sakila 数据库中的租赁数据学习最常用的函数,并了解它们的名称在不同数据库中有何不同。
几乎每张业务表都有日期:订单何时下单、电影何时租出、付款何时完成。“租了多久?”、“什么时候应该归还?”或“7 月有多少笔租赁?”这类问题都要用日期函数来回答。
示例使用 MySQL 和 MariaDB 语法。日期函数在不同数据库之间的差异比其他任何函数都大,因此本课末尾提供了一张对照表。
当前日期和时间
| 表达式 | 返回 | 示例 |
|---|---|---|
CURRENT_DATE | 当前日期 | 2026-10-16 |
CURRENT_TIME | 当前时间 | 14:25:30 |
CURRENT_TIMESTAMP 或 NOW() | 当前日期和时间 | 2026-10-16 14:25:30 |
SELECT CURRENT_DATE AS today,
CURRENT_TIME AS now_time,
NOW() AS now_datetime;
结果:一行数据,包含数据库服务器上的当前日期、时间以及日期时间。
CURRENT_DATE、CURRENT_TIME 和 CURRENT_TIMESTAMP 写时不带括号,它们是 SQL 标准表达式。该值在语句开始执行时就已确定,因此同一个查询中的所有行得到的时间都相同。
提取日期的各个部分
DATE() 和 TIME() 把日期时间值拆分为日期和时间;YEAR()、MONTH() 和 DAY() 返回单独的数字:
SELECT rental_date,
DATE(rental_date) AS rental_day,
TIME(rental_date) AS rental_time,
YEAR(rental_date) AS rental_year,
MONTH(rental_date) AS rental_month,
DAY(rental_date) AS day_of_month
FROM rental
LIMIT 3;
结果:前三笔租赁中的每一笔,其完整的日期时间被拆分为日期、时间、年、月和日。
标准函数 EXTRACT() 的作用相同,并且在大多数数据库中都能使用:
SELECT rental_date,
EXTRACT(YEAR FROM rental_date) AS rental_year,
EXTRACT(MONTH FROM rental_date) AS rental_month
FROM rental
LIMIT 3;
提取出的部分在过滤条件中很有用:
SELECT rental_id, rental_date
FROM rental
WHERE YEAR(rental_date) = 2005
AND MONTH(rental_date) = 7
LIMIT 5;
结果:2005 年 7 月的五笔租赁。
对列使用函数会使数据库无法利用该列上的索引。在大表上,使用日期范围更快:WHERE rental_date >= '2005-07-01' AND rental_date < '2005-08-01'。原因将在有关索引的课程中介绍。
加减时间间隔
DATE_ADD() 和 DATE_SUB() 按时间间隔移动日期。单位可以是 SECOND、MINUTE、HOUR、DAY、WEEK、MONTH 或 YEAR。
SELECT rental_id,
rental_date,
DATE_ADD(rental_date, INTERVAL 7 DAY) AS due_date,
DATE_SUB(rental_date, INTERVAL 1 MONTH) AS month_before
FROM rental
LIMIT 3;
结果:每笔租赁的日期、七天后的日期,以及一个月前的日期。
MySQL 和 MariaDB 也接受简写形式 rental_date + INTERVAL 7 DAY。
两个日期之间的差值
DATEDIFF(end, start) 返回两个日期之间相差的天数,并忽略时间部分:
SELECT rental_id,
rental_date,
return_date,
DATEDIFF(return_date, rental_date) AS days_rented
FROM rental
WHERE return_date IS NOT NULL
LIMIT 5;
结果:五笔已归还的租赁各自持续了多少个日历日。
TIMESTAMPDIFF(unit, start, end) 计算任意单位的完整数量;注意这里开始日期在前:
SELECT rental_id,
TIMESTAMPDIFF(HOUR, rental_date, return_date) AS hours_rented,
TIMESTAMPDIFF(DAY, rental_date, return_date) AS full_days_rented
FROM rental
WHERE return_date IS NOT NULL
LIMIT 5;
结果:以小时和完整的 24 小时天数表示的租赁时长。full_days_rented 可能小于按日历日计算的 DATEDIFF。
格式化日期
DATE_FORMAT(date, format) 按指定格式把日期转换为文本:
SELECT rental_date,
DATE_FORMAT(rental_date, '%d.%m.%Y') AS european_date,
DATE_FORMAT(rental_date, '%M %e, %Y %H:%i') AS long_date
FROM rental
LIMIT 3;
结果:日期显示为 24.05.2005 和 May 24, 2005 22:53。
| 格式符 | 含义 | 示例 |
|---|---|---|
%Y | 4 位年份 | 2005 |
%m | 2 位月份 | 05 |
%M | 月份名称 | May |
%d / %e | 带前导零 / 不带前导零的日 | 04 / 4 |
%H、%i、%s | 小时(24 小时制)、分钟、秒 | 22、53、30 |
DATE_FORMAT() 的结果是文本,而不是日期。只在输出时格式化日期;比较和排序时请使用原始的日期值。
其他数据库中的日期函数
| 任务 | MySQL / MariaDB | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|
| 当前日期和时间 | NOW() | NOW() | GETDATE() | datetime('now') |
| 日期的年份 | YEAR(d) | EXTRACT(YEAR FROM d) | YEAR(d) | strftime('%Y', d) |
| 加 7 天 | DATE_ADD(d, INTERVAL 7 DAY) | d + INTERVAL '7 days' | DATEADD(day, 7, d) | date(d, '+7 days') |
| 日期之间的天数 | DATEDIFF(d2, d1) | d2::date - d1::date | DATEDIFF(day, d1, d2) | julianday(d2) - julianday(d1) |
| 格式化日期 | DATE_FORMAT(d, '%d.%m.%Y') | TO_CHAR(d, 'DD.MM.YYYY') | FORMAT(d, 'dd.MM.yyyy') | strftime('%d.%m.%Y', d) |
EXTRACT(part FROM date) 和 CURRENT_DATE / CURRENT_TIMESTAMP 属于标准,几乎在所有数据库中都能使用。
要点:
CURRENT_DATE、CURRENT_TIMESTAMP和NOW()返回当前日期和时间。DATE()、YEAR()、MONTH()、DAY()和EXTRACT()提取日期的各个部分。DATE_ADD()和DATE_SUB()按时间间隔移动日期。DATEDIFF()计算日历日;TIMESTAMPDIFF()计算任意单位的完整数量。DATE_FORMAT()返回文本:用于输出,而不是比较。- 日期函数的名称在不同数据库中差异很大;切换数据库时请参考上表。
常见问题
如何在 SQL 中获取当前日期?
只要日期时使用 CURRENT_DATE,需要日期和时间时使用 CURRENT_TIMESTAMP 或 NOW()。在 SQL Server 中,使用 GETDATE() 或 CAST(GETDATE() AS DATE)。
如何在 SQL 中计算两个日期之间的天数?
在 MySQL 和 MariaDB 中,使用 DATEDIFF(end_date, start_date)。在 SQL Server 中,使用 DATEDIFF(day, start_date, end_date)。在 PostgreSQL 中,直接用一个日期减去另一个日期:end_date::date - start_date::date。
如何在 SQL 中给日期加上天数?
在 MySQL 和 MariaDB 中,使用 DATE_ADD(date, INTERVAL 7 DAY) 或 date + INTERVAL 7 DAY。在 PostgreSQL 中,使用 date + INTERVAL '7 days';在 SQL Server 中,使用 DATEADD(day, 7, date)。