SQL返回2个日期之间的小时数,不包括周末和非班次小时

时间:2014-04-28 17:34:04

标签: sql-server datetime

我想使用开始日期和结束日期来计算项目的使用时间。开始&结束日期将始终是工作日,但当然可以跨越多个星期。我已经努力排除周末但不确定如何排除非工作时间。

示例:

declare @d1 datetime, @d2 datetime
select @d1 = '04/25/2014 02:42',  @d2 = '04/28/2014 17:14'

select (datediff(mi, @d1, @d2) / 60) - (datediff(wk, @d1, @d2) * 48)

工作时间是星期一06:00 - 星期五21:00。

所以在所说的例子中,它返回38,但它应该是29,我相信。

任何帮助将不胜感激!感谢。

[编辑]

@Fnightangel

你我的朋友,是个天才!非常感谢你。这是一个很好的解决方案 - 清晰&简洁而有效的待遇:)。

我通过将这个IF语句添加到逻辑的开头来改进你的代码(正如你自己提到的,它不是100%正确):

IF (DATEDIFF(DD, @D1, @D2) <= 0) OR (DATEDIFF(WK, @D1, @D2) * 2 <= 0)
    RETURN
      (DATEDIFF(MI, @D1, @D2) / 60)
ELSE
    ....

1 个答案:

答案 0 :(得分:1)

我真的不知道这是否是最佳解决方案,但却是我唯一能想到的解决方案。

看看这是否有帮助:

定义变量

DECLARE @D1 DATETIME, @D2 DATETIME, @CURRENTDATE DATETIME
SELECT @D1 = '04/25/2014 02:42',  @D2 = '04/28/2014 17:14'

然后,我创建了2个表,存储所有星期一和星期五以后计算我们需要多少小时

CREATE TABLE #MONDAYS(MONDAYS VARCHAR(8) NULL)
CREATE TABLE #FRIDAYS(FRIDAYS VARCHAR(8) NULL)

SET @CURRENTDATE = CONVERT(VARCHAR(8), @D1, 112)
WHILE @CURRENTDATE <= CONVERT(VARCHAR(8), @D2, 112)
BEGIN
    IF DATEPART(DW, @CURRENTDATE) = 2 --MONDAY
        INSERT INTO #MONDAYS(MONDAYS) VALUES (CONVERT(VARCHAR(8), @CURRENTDATE, 112))
    ELSE
        IF DATEPART(DW, @CURRENTDATE) = 6 --FRIDAY
            INSERT INTO #FRIDAYS(FRIDAYS) VALUES (CONVERT(VARCHAR(8), @CURRENTDATE, 112))

    SET @CURRENTDATE = DATEADD(DAY, 1, CONVERT(VARCHAR(8), @CURRENTDATE, 112))
END

根据星期一和星期五计算非工作时数

DECLARE @NONWORKING AS INT

SET @NONWORKING = ((SELECT COUNT(*) FROM #FRIDAYS) * 3) -- 3 NON WORKING HOURS ON FRIDAYS
                + ((SELECT COUNT(*) FROM #MONDAYS) * 6) -- 6 NON WORKING HOURS ON MONDAYS

最后,计算

SELECT
(DATEDIFF(MI, @D1, @D2) / 60) 
- (DATEDIFF(WK, @D1, @D2) * 48)
- @NONWORKING

希望这会有所帮助。随意改善我的意识形态。