【问题标题】:SQL Sever - Datediff, hours, but exclude Saturday/ SundaysSQL Server - Datediff,小时,但不包括周六/周日
【发布时间】:2017-02-28 23:24:00
【问题描述】:

我想知道如何计算 SQL Server 中两个时间戳(例如 2016 年 2 月 24 日 17:30:00 和另一个)之间的“小时数”,但不包括周六和周日的完整 48 小时时段,如果越过。

这与纯粹的工作时间不太一样,但在某种程度上。这样做的原因是冗长且不必要的。

编辑:我也可以说结束日期总是在一周内。所以真的......“开始日期”可以简单地转换为星期一午夜,如果在星期六/星期日......那么也许一个函数包括总周数......

【问题讨论】:

  • datediff(hour, date, date2) - datediff(week, date1, date2) * 48?
  • 很难使用单个查询,由于第一天或最后一天可能是星期六或星期日。我做了类似的事情,但整天here
  • 嗯,我看了你的例子,可能会更深入地挖掘它,但似乎非常冗长。我在想…… datediff(hour,date1,date2) 是一个很好的基线——有没有办法计算两个日期之间的“周日时间”和“周六时间”?我想这是同样的问题。
  • 接受stackoverflow.com/questions/252519/… 的答案可能是一个很好的起点 - 需要调整几个小时而不是几天,以及日期范围在周末开始或结束的情况
  • 如果您的开始和结束日期可以是星期六或星期日,那么您需要生成开始日期和结束日期之间的所有日期,然后不包括您的 datepart(weekday, date) 所在的日期(1, 7)。

标签: sql-server datetime datediff business-logic


【解决方案1】:

DATEDIFF(Week, date, date2) 将返回两个日期之间跨越的周数。对于 SQL Server,这意味着日期之间有多少个星期日(而不是它们之间有 7 天的周期数)。这意味着,如果您确实可以假设开始日期和结束日期不是星期六或星期日,您可以从正常的DATEDIFF 调用中减去48 X DATEDIFF(Week, date, date2),这应该会给您之后的内容。

【讨论】:

  • 您好 --- 这是一个很好的起点。 END 点不能是周六/周日。但是,开始日期可以。我觉得只需要检查一下“开始日期”是否是周六和周日——如果是,则将这个时间转换为下周一的午夜。一旦发生这种情况,我认为你的方法会奏效。嗯——我认为这就是所有必要的。
【解决方案2】:

我会使用下面的代码

declare @NumberOfHours int

declare @StartTime datetime
declare @EndTime datetime

set @StartTime = '2017-02-02 17:30:00.000'
set @EndTime = '2017-02-07 00:00:00.000'

set @NumberOfHours = DATEDIFF(HOUR,@StartTime,@EndTime)

if(datepart(WEEKDAY, @StartTime)=1)
begin
    set @NumberOfHours = @NumberOfHours     DATEDIFF(HH,@StartTime,@EndTime)%24
end
else if(datepart(WEEKDAY, @StartTime)=7)
begin
    set @NumberOfHours = @NumberOfHours - DATEDIFF(HH,@StartTime,@EndTime)%24
    set @NumberOfHours = @NumberOfHours - 24
end
else
begin
    set @NumberOfHours = @NumberOfHours -  datediff(ww,@StartTime,@EndTime)*48
end
print @NumberOfHours

【讨论】:

    【解决方案3】:

    我会使用日历表(例如dbo.DateDimension,参考https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/):

    CREATE TABLE dbo.DateDimension
    (
      DateKey             INT         NOT NULL PRIMARY KEY,
      [Date]              DATE        NOT NULL,
      [Day]               TINYINT     NOT NULL,
      DaySuffix           CHAR(2)     NOT NULL,
      [Weekday]           TINYINT     NOT NULL,
      WeekDayName         VARCHAR(10) NOT NULL,
      IsWeekend           BIT         NOT NULL,
      IsHoliday           BIT         NOT NULL,
      ...
    )
    

    还有以下查询:

    SELECT SUM(
        CASE 
            WHEN dd.[Date] = CONVERT(DATE, @StartDate) THEN DATEDIFF(MINUTE, @StarDate, DATEADD(DAY, 1, dd.[Date]))
            WHEN dd.[Date] = CONVERT(DATE, @EndDate) THEN DATEDIFF(MINUTE, dd.[Date], @EndDate)
            ELSE 24 * 60 -- Full day
        END) / 60 AS SumOfHours
    FROM dbo.DateDimension dd
    WHERE dd.[Date] >= CONVERT(DATE, @StartDate) AND dd.[Date] <= CONVERT(DATE, @EndDate) 
    AND dd.IsWeekend = 0
    

    上面的查询将计算请求时间段的总分钟数,然后除以 60 得到小时数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 2019-02-04
      • 2016-07-11
      相关资源
      最近更新 更多