我有以下表格: -
表A(国定假日)
表B(时间表)
我希望计算正常工作时间&使用SQL Server在某些条件下为每位员工加班。预期的输出应该是这样的: -
条件如下: -
日班
周一至周五:最多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。
感谢。
答案 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]