🎯 本月只剩几天支持 SQLTest.online,帮助我们让 SQL 练习对每个人都免费。 今天捐赠 →
SQL 代码已复制到剪贴板

SQL 日期和时间函数

第 3.4 课 · 阅读时间:约 8 分钟 · 练习题 ↓

SQL 日期和时间函数可以返回当前日期、提取日期的各个部分、加减时间间隔、计算两个日期之间的差值,以及格式化日期以便输出。在本课中,你将通过 Sakila 数据库中的租赁数据学习最常用的函数,并了解它们的名称在不同数据库中有何不同。

几乎每张业务表都有日期:订单何时下单、电影何时租出、付款何时完成。“租了多久?”、“什么时候应该归还?”或“7 月有多少笔租赁?”这类问题都要用日期函数来回答。

示例使用 MySQL 和 MariaDB 语法。日期函数在不同数据库之间的差异比其他任何函数都大,因此本课末尾提供了一张对照表。

SQL 日期和时间函数:从日期中提取年、月、日,使用 DATE_ADD 加上时间间隔,以及计算两个日期之差的 DATEDIFF

当前日期和时间

表达式返回示例
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。

格式符含义示例
%Y4 位年份2005
%m2 位月份05
%M月份名称May
%d / %e带前导零 / 不带前导零的日04 / 4
%H、%i、%s小时(24 小时制)、分钟、秒22、53、30

DATE_FORMAT() 的结果是文本,而不是日期。只在输出时格式化日期;比较和排序时请使用原始的日期值。


其他数据库中的日期函数

任务MySQL / MariaDBPostgreSQLSQL ServerSQLite
当前日期和时间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::dateDATEDIFF(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)。

尝试解决以下任务,以巩固您在本课中学到的内容。

  1. 最高支付金额的月份
  2. 分析电影的租赁数据
  3. 平均客户活动持续时间
  4. 计算租赁延迟
  5. 按星期几的客户分布