我有一个基于时间戳的数据集,即startdate,enddate。我想计算时间戳之间的营业时间,比如典型的(M-F,8-5)周。
例如,如果一张票在星期一早上8点进入,并在星期二上午9点关闭,我希望该声明显示10小时。我还需要从计算中省略周末。有人可以推荐一种方法来解决这个问题吗?谢谢你的帮助。
答案 0 :(得分:0)
作为一个例子(没有你的桌面结构在我面前),这是我根据我为generating rows for time做的另一个答案提出的。
declare @datetimes table (id int primary key identity(1,1), startdatetime datetime, enddatetime datetime)
insert into @datetimes (startdatetime,enddatetime) values
('2014-08-26 08:00:00','2014-08-27 09:00:00')
, ('2014-07-16 08:00:00','2014-07-28 09:00:00')
declare @defaultDayStart time = '08:00:00', @defaultDayEnd time = '17:00:00'
select T.ID, sum(Z.ShadowHours)
from (
select id, startdatetime, enddatetime, datediff(hh,startdatetime,enddatetime) TotalTime
from @datetimes
) T
CROSS APPLY (
SELECT
RowID-1 AS ShadowDays
, CASE
WHEN DATENAME(dw,DATEADD(dd, RowID - 1,t.startdatetime)) IN ('Saturday', 'Sunday') THEN 0
ELSE DATEDIFF(hh, CASE RowID WHEN MIN(RowID)OVER(PARTITION BY t.id) THEN t.startdatetime ELSE CONVERT(DATETIME,CONVERT(DATE, DATEADD(dd, RowID - 1,t.startdatetime))) + @defaultDayStart END
, CASE RowID WHEN MAX(RowID)OVER(PARTITION BY t.id) THEN t.enddatetime ELSE CONVERT(DATETIME,CONVERT(DATE, DATEADD(dd, RowID - 1,t.startdatetime))) + @defaultDayEnd END
)
END AS ShadowHours
, DATENAME(dw,DATEADD(dd, RowID - 1,t.startdatetime)) wd
FROM (
SELECT ROW_NUMBER()OVER(ORDER BY S.NAME) AS RowID
FROM master..spt_values S
) X
WHERE DATEDIFF(dd,startdatetime,enddatetime) + 1 >= RowID
) Z
GROUP BY T.id
这个例子很简单,并没有使用包含例如假期的日历表。这也没有关于午餐时间的计算,这应该在那里,因为大多数地方认为在8小时工作日内不允许某种用餐休息是非法的。这些是您可能会被要求进行调整的注意事项。如果你想在这个领域获得帮助,请编辑你的问题并留下评论。