计算正常工作时间&随着时间的推移

时间:2014-01-16 02:53:36

标签: sql sql-server

我有以下表格: -

表A(国定假日)

enter image description here

表B(时间表)

enter image description here

我希望计算正常工作时间&使用SQL Server在某些条件下为每位员工加班。预期的输出应该是这样的: -

enter image description here

条件如下: -

日班

周一至周五:最多8小时被视为正常。 8小时以上被认为是OT15。 星期六:最多4小时被认为是正常的。 4小时以上被认为是OT15。 星期天&公众假期:被视为OT20

FEP部门:官方开始时间是早上7:30

Division SER:办公室开始时间是上午8:00

(出于计算目的,即使员工提前到达,开始时间也基于部门正式开始时间)

夜班

周一至周五:最多8小时被视为正常。 8小时以上被认为是OT15。 星期六:最多4小时被认为是正常的。 4小时以上被认为是OT15。 星期天&公众假期:被视为OT20

FEP部门:官方开始时间是晚上7:30

Division SER:办公室开始时间是晚上8点

除此之外,所有国定假日将被视为8小时正常工作,适合那些不工作的人。对于那些正在工作的人来说,它将被视为OT20。

感谢。

1 个答案:

答案 0 :(得分:1)

将其分解为多个部分,然后迭代:

-- To start with, we need to know how long someone actually worked
-- for each period, so let's calculate that:
;WITH EmployeeTimecardData AS
    (
    SELECT TS.[Date] AS [Period],
        TS.Employee AS [EmployeeID],
        SUM(DATEDIFF(MINUTE, TS.TimeIn, TS.TimeOut)) as [Time Worked],
        MAX(TS.[Day]) AS [DW]
    FROM Timesheet TS
    GROUP BY TS.[Date], TS.Employee
    ),
-- Then, there is some rounding that needs to be done,
-- (there is probably a better way to do this, but you get the idea)
EmployeeTimecards AS
    (
    SELECT ETD.[Perid],
        ETD.EmployeeID,
        CASE
        WHEN ROUND(ETD.[Time Worked], 1) % 10 > 0.5
            THEN CEILING(ETD.[Time Worked])
        WHEN ROUND(ETD.[Time Worked], 1) % 10 < 0.5
            THEN FLOOR(ETD.[Time Worked])
        ELSE
            ROUND(ETD.[Time Worked], 1)
        END AS [Time Worked],
        ETD.DW
    FROM EmployeeTimecardData AS [ETD]
    )
-- Now that we have the data in the shape we want it,
-- we can start our calculations
SELECT [ET].Period,
    [ET].EmloyeeID,
    CASE
    WHEN NHL.[Date] IS NOT NULL OR ET.DW = 'SUN'
        THEN 0
    WHEN ET.DW = 'SAT'
        THEN
            CASE
            WHEN ET.[Time Worked] > 4
                THEN 4
            ELSE
                ET.[Time Worked]
            END
    ELSE
        CASE
        WHEN ET.[Time Worked] > 8
            THEN 8
        ELSE
            ET.[Time Worked]
        END
    END AS [Normal],
-- OT15 and OT20 are left as an exercise for the reader :-)
FROM EmployeeTimecards AS [ET]
LEFT OUTER JOIN NationalHoliday [NHL]
    ON [ET].[Period] = [NHL].[Date]