【问题标题】:SQL - datediff (minutes) exclude weekendsSQL - datediff(分钟)不包括周末
【发布时间】:2013-03-19 13:28:14
【问题描述】:

你能帮帮我吗,我正在使用下面的 sql 视图(然后我在水晶报告中使用)。我需要日期差异(以分钟为单位),但现在我需要排除周末。 请帮忙:)

SELECT intwc                             AS wc,
       Datediff(n, start_date, end_date) AS time,
       mh_start_date                     AS date,
       'Repair'                          AS type
FROM   dbo.xxxxxxx 

【问题讨论】:

  • 您使用的是什么 DBMS?
  • 只是为了确认一下,Friday 11:30PMMonday 12:30AM 之间的区别你想看 60 分钟吗?
  • bendataclear-绝对是的
  • 我认为“计算工作天数”不适合这个问题。

标签: sql sql-server datediff


【解决方案1】:

这是@bendataclear 答案的修改版本。它直接计算周末分钟,而不是计算天数并乘以 24*60。它还解释了周六/周日开始/结束的所有 4 种组合

我使用CONVERT(date,@StartDate) 获取@StartDate 的日期和00:00:00 的时间,然后用于计算部分星期日和星期六。有better ways 这样做,但我选择了最简单的。

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2013/03/15 23:30:00'
SET @EndDate = '2013/03/17 00:30:00'


SELECT
(   DATEDIFF(MINUTE, @StartDate, @EndDate)
    - ( DATEDIFF(wk, @StartDate,@EndDate)*(2*24*60)
        -- End on Sunday
        -(CASE WHEN DATEPART(dw, @EndDate)  = 1 THEN 24.0*60-DATEDIFF(minute,CONVERT(date,@EndDate),@EndDate) ELSE 0 END)
        -- Start on Saturday
        -(CASE WHEN DATEPART(dw, @StartDate) = 7 THEN DATEDIFF(minute,CONVERT(date,@StartDate),@StartDate) ELSE 0 END)
        -- End on Saturday
        +(CASE WHEN DATEPART(dw, @EndDate)  = 7 THEN DATEDIFF(minute,CONVERT(date,@EndDate),@EndDate) ELSE 0 END)
        -- Start on Saturday
        +(CASE WHEN DATEPART(dw, @StartDate) = 1 THEN 24.0*60-DATEDIFF(minute,CONVERT(date,@StartDate),@StartDate) ELSE 0 END)
    )
)

【讨论】:

  • 对于额外分数,/60 这个答案乘以 60 将为您提供两个日期之间的总小时数,%60 将为您提供总分钟数。 (结果四舍五入)
【解决方案2】:

此答案假设您想以分钟为单位排除周末,它也完全基于this question 中的答案:

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2013/03/15 23:30:00'
SET @EndDate = '2013/03/18 00:30:00'


SELECT
   (DATEDIFF(MINUTE, @StartDate, @EndDate))
  -(DATEDIFF(wk, @StartDate, @EndDate) * (2*24*60))
  -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN (24*60) ELSE 0 END)
  -(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN (24*60) ELSE 0 END)

【讨论】:

  • 最后两行将减去整个 24*60 分钟,无论 StartDate 或 EndDate 是什么时间。但是,如果 EndDate 是在星期六的 0:30,那么应该只减去 30 分钟,而不是 24*60。在您的代码中尝试将 EndDate 更改为“2013/03/17 00:30:00”,它会给出一个负数。
【解决方案3】:
SELECT intwc                             AS wc,
   Datediff(n, start_date, end_date) AS time,
   mh_start_date                     AS date,
   'Repair'                          AS type
FROM   dbo.xxxxxxx 
Where DATEPART(dw, start_date) NOT IN (1, 7) and DATEPART(dw, end_date) NOT IN (1, 7)

【讨论】:

    【解决方案4】:

    因此,您确实需要能够处理一些 CASE 语句来处理所有边缘情况。这是我放在一起的一个例子。 Numbers 表只是一个计数表,在本例中为 1 到 30。

    CREATE TABLE #times (id INT IDENTITY(1,1), start_stamp DATETIME, end_stamp DATETIME)
    
    INSERT INTO #times
            ( 
              start_stamp ,
              end_stamp
            )
    SELECT DATEADD(DAY, -2*Number, CURRENT_TIMESTAMP), DATEADD(DAY, -1*Number, CURRENT_TIMESTAMP)
    FROM Common.NUMBERS
    WHERE Number < 31
    
    SELECT id, start_stamp, end_stamp,
    CASE WHEN DATEDIFF(DAY, start_stamp, end_stamp) < 7 THEN
        CASE WHEN DATEPART(weekday, start_stamp) < DATEPART(weekday, end_stamp)
            THEN DATEDIFF(MINUTE, start_stamp, DATEADD(HOUR, -48, end_stamp))
            ELSE DATEDIFF(MINUTE, start_stamp, end_stamp) END
        ELSE DATEDIFF(MINUTE, start_stamp, DATEADD(HOUR, -48*(DATEDIFF(WEEK, start_stamp, end_stamp)), end_stamp)) END
        + CASE WHEN DATENAME(weekday,start_stamp) IN ('Sunday', 'Saturday') THEN 1440 ELSE 0 END
        + CASE WHEN DATENAME(weekday,end_stamp) IN ('Sunday', 'Saturday') THEN 1440 ELSE 0 END
    FROM #times
    

    可能有一种更优雅的方法可以做到这一点,但代码允许您针对整个结果集运行并按行计算。

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2011-11-15
      • 2017-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 2021-05-05
      • 1970-01-01
      相关资源
      最近更新 更多