时间戳之间的总和

时间:2014-08-27 20:00:03

标签: sql timestamp calculated-columns

我有一个基于时间戳的数据集,即startdate,enddate。我想计算时间戳之间的营业时间,比如典型的(M-F,8-5)周。

例如,如果一张票在星期一早上8点进入,并在星期二上午9点关闭,我希望该声明显示10小时。我还需要从计算中省略周末。有人可以推荐一种方法来解决这个问题吗?谢谢你的帮助。

1 个答案:

答案 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小时工作日内不允许某种用餐休息是非法的。这些是您可能会被要求进行调整的注意事项。如果你想在这个领域获得帮助,请编辑你的问题并留下评论。