【问题标题】:DATEDIFF with WEEK/MONTH gives different result带有 WEEK/MONTH 的 DATEDIFF 给出不同的结果
【发布时间】:2014-07-08 21:22:45
【问题描述】:

我想知道两个日期之间的周差。看起来 SQL Server 确实完成了并为我提供了不同的结果。但我想计算他们是否跨越了 7、14、21 天。

我在数据库中存储了一周的差异,例如 1 或 2 等。所以我想将 DATEDIFF 与 WEEK 一起使用,而无需四舍五入。

预期结果 0,但返回 1

 SELECT DATEDIFF(WEEK, '2014-07-08 10:15:00', '2014-07-14 09:00:00'); --1

预期结果 1,但返回 2

 SELECT DATEDIFF(WEEK, '2014-07-08 10:15:00', '2014-07-20 09:00:00'); --2

MONTH 也有同样的问题,下面的预期行为是 0。但给出 1

 SELECT DATEDIFF(MONTH, '2014-07-15 10:15:00', '2014-08-12 09:00:00')  --1

如何获得正确的周/月差?

【问题讨论】:

标签: sql sql-server sql-server-2008


【解决方案1】:

根据 MSDN,DATEDIFF“返回在指定的开始日期和结束日期之间交叉的指定日期部分边界的计数(有符号整数)。”

在您的第一种情况下,datepart(week,'2014-07-08 10:15:00') 是 28,datepart(week,'2014-07-14 09:00:00') 是 29,因此您的结果应该是 1。其他情况类似。

我想您可以将日期时间值转换为 bigint,然后将差值除以 7 以获得周数,如果这是您正在寻找的,如下所示:

select (cast(@end as bigint) - cast(@start as bigint))/7

编辑:DATEDIFF 始终使用星期日作为一周的第一天,以确保函数具有确定性。

感谢@Serpiton 提供此信息。

【讨论】:

  • 只是在 MSDN 的another 页面中找到的一个小注释,您可能想要添加到答案中:DATEDIFF 始终使用星期日作为一周的第一天,以确保函数是确定性的。
  • 那么我的问题的解决方案是什么?
  • SELECT cast('2014-07-08 10:15:00' as bigint)- cast('2014-07-14 09:00:00'as bigint)/7Error converting data type varchar to bigint
  • 那是因为您传递的是一个文本字符串,而不是datetime 类型的变量。我假设您的实际列/变量是datetime 类型?如果没有,我建议你先输入datetime
  • Declare @sd smalldatetime='2014-07-08 10:15:00'; Declare @ed smalldatetime='2014-07-14 09:00:00'; SELECT cast(@sd as bigint)- cast(@ed as bigint)/7 给出的结果为 35850.. 这个数字是多少?我期待 0 :(.. 我的意思是 0 周
【解决方案2】:

您可以在 DATEDIFF 函数中尝试 DAY 而不是 WEEK,然后除以 7 得到完整的一周

SELECT DATEDIFF(DAY, '2014-07-08 10:15:00', '2014-07-20 09:00:00') / 7

【讨论】:

  • 但是如果我处理的是月,而不是周,我需要除以 30/31/28 吗?
  • ` SELECT DATEDIFF(MONTH, '2014-07-15 10:15:00', '2014-08-12 09:00:00')` 还给出了 1. 如何处理这个问题。
  • 问题是你希望这个如何返回,你想把 30/31/28 天作为一个月,还是从日期和今天跨越一个完整的月。例如 1 月 15 日到 3 月 15 日,它是否应该返回 1,因为只有 feb 是该范围内的完整月份,但如果我们从日期角度来看,它是 2。
【解决方案3】:

您的问题的解决方案

SELECT DATEDIFF(DD, '2014-07-08 10:15:00', '2014-07-14 09:00:00')/7
SELECT DATEDIFF(DD, '2014-07-08 10:15:00', '2014-07-15 09:00:00')/7
SELECT DATEDIFF(DD, '2014-07-08 10:15:00', '2014-07-20 09:00:00')/7
SELECT DATEDIFF(DD, '2014-07-08 10:15:00', '2014-07-22 09:00:00')/7

【讨论】:

    【解决方案4】:

    Kiran Hedge 的回答涵盖了几周,你可以使用几个月

    declare @datestart datetime = '2014-07-09 10:15:00'
    declare @datestop datetime = '2014-08-08 09:00:00'
    
    SELECT DATEDIFF(MONTH, @datestart, @datestop)
         - CAST(((DATEPART(DAY, @datestart))
          / (DATEPART(DAY, @datestop) + 1)) AS BIT)
    

    如果天数相同则算作一个月,CASTBIT 是将每个数字减为 1。

    【讨论】:

    • SELECT DATEDIFF(MONTH, '2014-07-15 10:15:00', '2014-08-15 09:00:00')- (DATEPART(DAY, '2014-07-15 10:15:00')/ DATEPART(DAY, '2014-08-15 09:00:00')) 它没有给出 1 :(
    猜你喜欢
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多