在计算工作时间方面需要帮助

时间:2010-10-04 16:50:47

标签: sql sql-server tsql sql-server-2008

alt text

我设计工作表的方式无法帮助我轻松计算工作时间。

快照中的输出已从多个表中收集。

不要担心setDate和timeEntered格式。

SetDate代表工作日。 tsTypeTitle表示班次的类型,是午餐时间等。 timeEntered表示实际时间。

setDate必须被修剪为只有Date和timeEntered应该只显示时间 - 这将在稍后处理,不用担心。

我需要抓住Shift Started和Shift Ended之间的区别,这样我才能计算出工资。

以下是我的查询,以便您查看它:

SELECT TimeSheet.setDate, TimeSheetType.tsTypeTitle, TimeSheetDetail.timeEntered
FROM TimeSheet 
    INNER JOIN TimeSheetDetail 
        ON TimeSheet.timeSheetID = TimeSheetDetail.timeSheetID
    INNER JOIN TimeSheetType 
        ON TimeSheetType.timeSheetTypeID = TimeSheetDetail.timeSheetTypeID

3 个答案:

答案 0 :(得分:1)

假设每个人每天都有相同的4个事件(轮班开始/结束,午餐开始/结束),你可以做这样的事情。显然我已经为你的TimeSheetType ID值做了假设。替换您的版本中的相应ID。

SELECT t.TimeSheetID, DATEDIFF(HOUR, tsd1.timeEntered, tsd4.timeEntered) - DATEDIFF(HOUR, tsd2.timeEntered, tsd3.timeEntered) as WorkingHours
    FROM TimeSheet t
        INNER JOIN TimeSheetDetail tsd1
            ON t.timeSheetID = tsd1.timeSheetID
                and tsd1.timeSheetTypeID = 1 /* Shift Started */
        INNER JOIN TimeSheetDetail tsd2
            ON t.timeSheetID = tsd2.timeSheetID
                and tsd2.timeSheetTypeID = 2 /* Lunch Started */
        INNER JOIN TimeSheetDetail tsd3
            ON t.timeSheetID = tsd3.timeSheetID
                and tsd3.timeSheetTypeID = 3 /* Lunch Ended */
        INNER JOIN TimeSheetDetail tsd4
            ON t.timeSheetID = tsd4.timeSheetID
                and tsd4.timeSheetTypeID = 4 /* Shift Ended */

答案 1 :(得分:1)

如果你必须在数据库中执行此操作,我建议编写一个存储过程来计算工作小时数。否则,我认为在数据库之外处理这种业务逻辑比较明智,就像连接到数据库的应用程序一样。

查看您提供的设计,您似乎缺少与存储的时间表数据相对应的用户或个人的唯一标识符。即使您目前仅存储单个用户/个人的数据,也需要唯一标识符。如果您需要为更多用户/人员存储数据,那么拥有唯一标识符就可以实现这一目标。

答案 2 :(得分:0)

时间表详细信息表通常包含人员ID。我想这是为了简单起见省略了。

假设任何一天都会有一个且只有一个事件,分别为Shift Started,Lunch Started,Lunch Ended和Shift Ended(按此顺序), 午餐应该从总小时数中排除,并且没有其他事件类型,请尝试:

with
(SELECT TimeSheet.setDate, 
       TimeSheetType.tsTypeTitle, 
       TimeSheetDetail.timeEntered,
       convert(datetime,convert(varchar(10),TimeSheetDetail.timeEntered,112),112) dayEntered
FROM TimeSheet 
    INNER JOIN TimeSheetDetail 
        ON TimeSheet.timeSheetID = TimeSheetDetail.timeSheetID
    INNER JOIN TimeSheetType 
        ON TimeSheetType.timeSheetTypeID = TimeSheetDetail.timeSheetTypeID)
as TS
select dayEntered, 
       datediff(ss,max(case when tsTypeTitle = 'Shift Started' then timeEntered end),
                   max(case when tsTypeTitle = 'Shift Ended' then timeEntered end)) -
       datediff(ss,max(case when tsTypeTitle = 'Lunch Started' then timeEntered end),
                   max(case when tsTypeTitle = 'Lunch Ended' then timeEntered end)) daysSeconds
from TS
group by dayEntered