跳至主要内容

DATEDIFF() SQL FUNCTION

DATEDIFF() 是 SQL 中最常用的日期数据处理函数之一。阅读本教程即可掌握它。
· 3分钟 阅读

使用 AI 探索

DATEDIFF() 是 SQL 中最常用的日期与时间处理函数之一。本文将带您了解其用法、语法,以及在主流 SQL 方言中的关键差异,帮助您熟练掌握这一强大的函数。

什么是 DATEDIFF() 函数?

DATEDIFF() 用于计算两个日期或时间戳之间的差值,并以指定的单位返回结果,例如天、月或年。

不同 SQL 方言中的 DATEDIFF 语法

DATEDIFF() 的语法在不同的 SQL 方言中有所不同。以下是常用数据库的示例:

 

以下是包含所有所需改进与增强的完整更新文章:


DATEDIFF() SQL 函数

DATEDIFF() 是 SQL 中最常用的日期与时间处理函数之一。本文将带您了解其用法、语法,以及在主流 SQL 方言中的关键差异,帮助您熟练掌握这一强大的函数。


什么是 DATEDIFF() 函数?

DATEDIFF() 用于计算两个日期或时间戳之间的差值,并以指定的单位返回结果,例如天、月或年。


不同 SQL 方言中的 DATEDIFF 语法

DATEDIFF() 的语法在不同的 SQL 方言中有所不同。以下是常用数据库的示例:

SQL Server

DATEDIFF(datepart, startdate, enddate)
  • datepart:时间单位(例如 year、month、day)。
  • startdate 与 enddate:要比较的日期或时间戳。结果按 enddate - startdate 计算。

MySQL

DATEDIFF(enddate, startdate)
  • 仅返回天数差。

PostgreSQL

PostgreSQL 没有 DATEDIFF() 函数,但可通过以下方式实现类似功能:

  • AGE() 函数:
SELECT AGE(enddate, startdate);
  • 直接相减日期值:
SELECT enddate - startdate;

参数

含义

datepart

必需参数。用于指定 DATEDIFF() 报告 startdate 与 enddate 差值的时间单位。其可取值见下节。

startdate

必需参数,表示起始日期时间值。

enddate

必需参数,表示结束日期时间值。

datepart 语法

datepart 参数用于定义计算差值的时间单位。SQL Server 支持以下 datepart 取值:

时间单位别名
yearyy, yyyy
quarterqq, q
monthmm, m
daydd, d
hourhh
minutemi, n
secondss, s
millisecondms

注意:MySQL 在 DATEDIFF() 中仅支持以 day 为单位。

  • 引号:日期与时间值请始终使用单引号(')。
  • 正负结果:在 SQL Server 中,若 enddate > startdate,结果为正,否则为负。
  • 错误处理:若结果超出 ±2,147,483,647,请在 SQL Server 中使用 DATEDIFF_BIG()。

DATEDIFF() 示例

使用 DATEDIFF() 时,结果可能为正或为负。若 enddate 晚于 startdate,则返回正数;若 enddate 早于 startdate,则返回负数。

示例 1:计算两个日期之间的差值

在 SQL Server 中:

SELECT DATEDIFF(year, '2022-12-31', '2024-06-01') AS years_difference;

说明:该语句计算两日期之间的年份差。由于计入了 2023 年和 2024 年的一部分,结果为 1。

在 MySQL 中:

SELECT DATEDIFF('2024-06-01', '2022-12-31') AS days_difference;

说明:MySQL 仅支持天数差。结果为 518。

示例 2:计算两个时间戳之间的差值

SELECT 
    DATEDIFF(hour, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS hours_difference,
    DATEDIFF(minute, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS minutes_difference,
    DATEDIFF(second, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS seconds_difference;

说明:

  • hours_difference 返回 23,因为两者相差 23 小时。
  • minutes_difference 返回 1439,即 23 hours * 60 minutes。
  • seconds_difference 返回 86,399,即 1439 minutes * 60 seconds。

示例 3:计算两个日期列之间的差值

假设您有一张 orders 表,包含 order_date 和 shipped_date。可使用 DATEDIFF() 计算每笔订单的发货用时。

SELECT 
    order_id,
    DATEDIFF(day, order_date, shipped_date) AS shipping_days 
FROM sales.orders;

说明:该查询计算每笔订单发货所需的天数。

示例 4:计算今日与某列日期之间的间隔

延续示例 3 的 sales.orders 表,我们可以使用 DATEDIFF() 计算今日与下单日期之间的天数。

SELECT 
    order_id,
    order_date,
    GETDATE() AS today_date,
    DATEDIFF(day, order_date, GETDATE()) AS days_from_order;

说明:

  • GETDATE() 在 SQL Server 中用于获取当前日期和时间。
  • 计算从 order_date 到今日的天数差。

补充说明

当结果超出范围(即大于 +2,147,483,647 或小于 -2,147,483,647)时,DATEDIFF() 会返回错误。在这种情况下,请使用 DATEDIFF_BIG()。

常见错误与排查

使用 DATEDIFF() 时,常见问题包括语法、参数顺序或特定数据库行为差异。以下为常见错误及其解决方法:

1. 引号使用不当

问题:给 datepart 加引号,或日期字面量使用不一致的引号风格。

解决:datepart 不要加引号,日期请使用单引号。

-- 错误示例
SELECT DATEDIFF('year', '2023-01-01', '2024-01-01');

-- 正确示例
SELECT DATEDIFF(year, '2023-01-01', '2024-01-01');
 

2. MySQL 中不支持的 datepart

问题:MySQL 的 DATEDIFF() 仅支持天数差。

解决:对于年份或月份等更细粒度单位,请使用 TIMESTAMPDIFF()。

-- 正确用法(MySQL)
SELECT TIMESTAMPDIFF(YEAR, '2023-01-01', '2024-01-01') AS years_difference; -- 返回 1

3. 参数顺序很重要

问题:颠倒 startdate 与 enddate 会得到意外的负值。

解决:确保 startdate 在前。若只关心绝对值,可使用 ABS()。

-- 错误示例
SELECT DATEDIFF(day, '2023-01-05', '2023-01-01'); -- 返回 -4

-- 正确示例
SELECT DATEDIFF(day, '2023-01-01', '2023-01-05'); -- 返回 4

4. 与地区相关的日期格式

问题:含混的日期格式(如 MM/DD/YYYY 与 DD/MM/YYYY)可能导致错误。

解决:使用 ISO 8601 标准(YYYY-MM-DD)以避免歧义。

-- 正确示例
SELECT DATEDIFF(day, '2023-01-01', '2023-12-31'); -- 返回 364

5. 超出范围的取值(SQL Server)

问题:超过 ±2,147,483,647 的巨大差值会引发溢出错误。解决:对大范围计算使用 DATEDIFF_BIG()。

-- 正确示例
SELECT DATEDIFF_BIG(day, '0001-01-01', '9999-12-31'); -- 返回 2,920,862,800

技术要求

适用于 SQL Server(自 2008 起)、Azure SQL Database、Azure SQL Data Warehouse、Parallel Data Warehouse

参见

进一步学习 SQL

Travis Tang

作者

Travis Tang

作为抖音的数据科学家兼佐治亚理工学院硕士生,我对数据科学怀有与生俱来的热情,并开辟了一条将技术、风险与持续自我提升相融合的独特职业路径。在 Merchant Platform 担任数据科学家期间,我运用复杂的数据模型降低风险、打击欺诈,每周为公司节省数千美元。我通过大量自学不断打磨专业能力,获得多家知名机构的认证,并熟练掌握深度学习、TensorFlow 和社会网络分析等领域。在 DataCamp 及其他教育平台上,我以此积累的知识启发并教育他人,在数据科学领域开辟新路径,也证明了只要有决心并掌握正确的数据,任何风险都能转化为机遇。

主题