【发布时间】:2015-09-14 14:21:12
【问题描述】:
我需要获取两个日期时间之间的分钟数。问题是我只需要计算一周中的分钟数。我的周末时间不算在内。另外,我们将周末定义为从周五下午 5 点开始,到周一上午 8 点结束。我相信我已经创建了一个函数来计算一周中的时间,但它没有考虑周五 17:00-23:59 和周一 00:00-7:59 之间的时间。此计算可能跨越数周,因此需要每周过滤掉这个时间。
一些预期结果的例子是:
- 09/09/15 09:15 - 09/10/15 18:30 = 1995 分钟
- 09/09/15 09:15 - 09/11/15 18:30 = 3345 分钟(柜台只到周五下午 5 点)
- 09/09/15 09:15 - 09/12/15 18:30 = 3345 分钟
- 09/09/15 09:15 - 09/13/15 18:30 = 3345 分钟
- 09/09/15 09:15 - 09/14/15 18:30 = 3975 分钟(周一晚上 8 点开始计时)
- 09/11/15 18:30 - 09/12/15 18:30 = 0 分钟(因为柜台在周五下午 5 点之后开始,直到周一早上 8 点才开始。
- 09/12/15 18:30 - 09/14/15 18:30 = 630 分钟
这是目前为止的功能:
IF OBJECT_ID(N'WorkDaysMinutes', N'FN') IS NOT NULL
DROP FUNCTION [dbo].[WorkDaysMinutes]
GO
CREATE FUNCTION [dbo].[WorkDaysMinutes] (@StartDate DATETIME, @EndDate DATETIME = NULL) RETURNS FLOAT
AS
BEGIN
DECLARE @Swap DATETIME
DECLARE @Weekend_Start_Time NVARCHAR(5)
DECLARE @Weekend_End_Time NVARCHAR(5)
SET @Weekend_Start_Time = '17:00'
SET @Weekend_End_Time = '08:00'
IF @StartDate IS NULL
RETURN NULL
IF @EndDate IS NULL
SELECT @EndDate = @StartDate
IF @StartDate > @EndDate
SELECT @Swap = @EndDate,
@EndDate = @StartDate,
@StartDate = @Swap
RETURN (
SELECT
--Start with total number of minutes including weekends
DATEDIFF(MI,@StartDate, @EndDate)
--Subtact 2880 minutes for each full weekend
-(DATEDIFF(wk, DATEADD(dd,-1,@StartDate), DATEADD(dd,-1,@EndDate)) * 2880)
--If StartDate is a Weekend, Subtract time untill monday
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN DATEDIFF(MI,@StartDate,DATEADD(d,0,DATEDIFF(d,-1,@StartDate))) ELSE 0 END)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Saturday' THEN DATEDIFF(MI,@StartDate,DATEADD(d,0,DATEDIFF(d,-1,@StartDate))) + 1440 ELSE 0 END)
--If EndDate is a Weekend, Subtract time since friday
-(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN DATEDIFF(mi,CONVERT(varchar(10),@EndDate,112),@EndDate) ELSE 0 END)
-(CASE WHEN DATENAME(dw, @EndDate) = 'Sunday' THEN DATEDIFF(mi,CONVERT(varchar(10),@EndDate,112),@EndDate) + 1440 ELSE 0 END)
--Subtract all holidays
-((SELECT Count(*)
FROM SY_Holiday H
WHERE H.Date BETWEEN @StartDate AND @EndDate
AND DATEPART(DW,H.Date) NOT IN (6,7)) * 1440)
)
END
GO
编辑:我们还需要考虑假期。这些假期存储在表 SY_Holiday 中。如果假期在周六或周日,则无关紧要,不应扣除,但如果假期在周二至周四,我们将每天扣除 1440。如果假期是在星期五,那么我们需要从星期四下午 5 点到星期五下午 5 点之间扣除时间。这同样适用于星期一。这应该只是意味着减去一个 1440 应该没问题。
【问题讨论】:
-
国定假日等非工作日呢?
-
谢谢你提醒我,我忘了说,这就是我们的假期表。这将跟踪那些日子,它应该从总数中扣除。我已经编辑了原始帖子以突出显示假期。
-
与其仅仅实现一个holiday表,为什么不引入一个calendar表呢?每天一行,20 年的行数只有 7000 行。您可以添加有用的列,例如每天工作的开始时间和结束时间,然后将此查询简化为仅从该表中查找与给定日期重叠的行,并对找到的每一天的工作时间求和。
-
好吧,我咬牙切齿....我们将如何进行比较?
标签: sql sql-server-2008 tsql