当前位置:首页 > 问答 > 正文

MSSQL里时间格式加减怎么弄才又快又准,别整复杂了直接用函数就行

DATEADD 和 DATEDIFF

把这两个函数用熟了,绝大部分时间加减的问题都能解决。

做加法:就用 DATEADD

这个函数是专门用来给某个日期时间加一段间隔的,它的写法很固定:

DATEADD(间隔类型, 间隔数值, 原始日期)
  • 间隔类型:就是你要加的是年、月、天还是小时,直接用英文缩写就行,最常用的有:
    • yearyyyyyy (年)
    • quarterqqq (季度)
    • monthmmm (月)
    • dayddd (天)
    • weekwkww (周)
    • hourhh (小时)
    • minutemin (分钟)
    • secondsss (秒)
  • 间隔数值:就是一个整数,可以是正数(表示加),也可以是负数(表示减)。
  • 原始日期:就是你要处理的哪个时间。

举几个例子,一看就懂:

  1. 加天数:给今天加10天。

    SELECT DATEADD(day, 10, GETDATE()) AS 十天后的日期;

    这里的 GETDATE() 就是获取当前时间。

  2. 减月份:从某个特定日期(2023-01-15')减3个月。

    SELECT DATEADD(month, -3, '2023-01-15') AS 三个月前的日期;
  3. 加小时:在当前时间上加5个小时。

    MSSQL里时间格式加减怎么弄才又快又准,别整复杂了直接用函数就行

    SELECT DATEADD(hour, 5, GETDATE()) AS 五小时后的时间;

DATEADD 函数最棒的地方是它很“智能”,比如你给1月31日加一个月,它会返回2月的最后一天(28或29日),而不是得出一个不存在的2月31日,这比自己用数字去加减要可靠得多。

做减法和计算间隔:就用 DATEDIFF

这个函数是用来计算两个日期之间相差多少个指定的时间间隔,写法是:

DATEDIFF(间隔类型, 开始日期, 结束日期)

它会返回(结束日期 - 开始日期)的差值,单位是你指定的间隔类型。

同样,举例子:

  1. 计算年龄:计算某人生日('1990-05-20')到现在的年龄(相差多少年)。

    SELECT DATEDIFF(year, '1990-05-20', GETDATE()) AS 年龄;

    注意:这个计算是整年数,如果今天还没到生日那天,会少算一岁,更精确的计算需要结合CASE WHEN,但简单看岁数这就够了。

    MSSQL里时间格式加减怎么弄才又快又准,别整复杂了直接用函数就行

  2. 计算天数差:计算从年初到今天一共过了多少天。

    SELECT DATEDIFF(day, '2024-01-01', GETDATE()) AS 今年过了多少天;
  3. 计算分钟差:计算两个精确时间点相差多少分钟。

    SELECT DATEDIFF(minute, '2024-05-27 09:00:00', '2024-05-27 11:30:00') AS 相差分钟数;

重要提示DATEDIFF 只关心“边界”次数,比如计算两个日期相差多少天,它只看日期部分,忽略时间,计算相差多少个月,它只看月份和年份的变化,这通常就是我们想要的,但如果你需要精确到秒级的差值,就要用 second 作为单位。

组合使用,解决常见问题

DATEADDDATEDIFF 结合起来,可以解决一些很实际的问题。

经典场景1:获取本月的第一天

思路是:先计算当前日期和某个固定起点(1900-01-01')相差了多少个月,然后把这个月数加回到起点上,得到的就是当月的第一天。

MSSQL里时间格式加减怎么弄才又快又准,别整复杂了直接用函数就行

SELECT DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AS 本月第一天;

这里的 0 在MSSQL里代表一个起始日期'1900-01-01',是一种常见的简写。

经典场景2:获取本周的星期一

思路类似:计算当前日期和某个已知的星期一相差了多少周,然后把周数加回去。

-- 假设 '19000101' 是星期一(实际上它是星期几不重要,关键是设定一个基准)
SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()), 0) AS 本周星期一;

更精确的写法可能需要考虑一周起始日是星期天还是星期一,可以通过 SET DATEFIRST 设置,但上面这个是最通用的写法。

为什么这样又快又准?

  1. 快(性能好)DATEADDDATEDIFF 是MSSQL内置的函数,底层优化得很好,如果你自己写表达式,比如用 原始日期 + 1 来加一天,虽然有时也行,但MSSQL最终可能还是要把它转换成内置函数来执行,直接使用标准函数,能让查询优化器更好地理解你的意图,从而使用索引(如果存在的话),避免全表扫描。

  2. 准(避免错误):如前所述,这些函数会自动处理闰年、月末等边界情况,如果你手动计算,比如用 天数 * 24 * 60 * 60 来换算秒数,很容易因为考虑不周而出错,尤其是在涉及夏令时(虽然MSSQL服务器时间通常不考虑这个)或者月末日期时。

总结一下

别再想什么复杂的方法了,

  • 要加减时间:用 DATEADD(单位, 数量, 日期)
  • 要计算时间差:用 DATEDIFF(单位, 开始日期, 结束日期)

把这两个函数当成你的左膀右臂,MSSQL里的时间计算就变得非常简单直接了,多写几次,肌肉记忆就形成了,根本不用死记硬背。