我想知道一名员工在工作时间内外办公室的工作时数。
以下是员工的工作时间
案例#1
FromDateTime ToDateTime
---------------------------------------------------
2017-12-11 07:30:00.000 2017-12-11 12:30:00.000
2017-12-11 15:30:00.000 2017-12-11 18:30:00.000
以下是员工的出勤时间(办公时间内)
InTime OutTime
--------------------------------------------------------
2017-12-11 07:30:12.000 2017-12-11 07:34:29.000
2017-12-11 12:45:28.000 2017-12-11 13:04:15.000
2017-12-11 17:55:15.000 2017-12-11 18:04:28.000
当您比较上述两个表时,预期的内部和外部时间与工作时间的关系应低于:
FromTime ToTime Remarks
-----------------------------------------------------------------------
2017-12-11 07:30:12.000 2017-12-11 07:34:29.000 Inside Office
2017-12-11 07:34:29.000 2017-12-11 12:30:00.000 Outside Office
2017-12-11 12:45:28.000 2017-12-11 13:04:15.000 Inside Office
2017-12-11 15:30:00.000 2017-12-11 17:55:15.000 Outside Office
2017-12-11 17:55:15.000 2017-12-11 18:04:28.000 Inside Office
2017-12-11 18:04:28.000 2017-12-11 18:30:00.000 Outside Office
但我得到的结果为:
FromTime ToTime Remarks
-----------------------------------------------------------------------
2017-12-11 07:30:00.000 2017-12-11 07:30:12.000 Outside Office
2017-12-11 07:30:12.000 2017-12-11 07:34:29.000 Inside Office
2017-12-11 07:34:29.000 2017-12-11 12:45:28.000 Outside Office
2017-12-11 12:45:28.000 2017-12-11 13:04:15.000 Inside Office
2017-12-11 15:30:00.000 2017-12-11 17:55:15.000 Outside Office
2017-12-11 17:55:15.000 2017-12-11 18:04:28.000 Inside Office
2017-12-11 18:04:28.000 NULL Outside Office
我希望我清除了我的问题,下面是我为此目的编写的查询:
DECLARE @EmployeeDutyHours TABLE
(
FromDateTime DATETIME,
ToDateTime DATETIME
)
DECLARE @EmployeeAttendanceHours TABLE
(
InTime DATETIME,
OutTime DATETIME
)
INSERT INTO @EmployeeDutyHours
VALUES ('2017-11-29 07:30:00.000', '2017-11-29 12:30:00.000'),
('2017-11-29 13:30:00.000', '2017-11-29 16:30:00.000')
INSERT INTO @EmployeeAttendanceHours
VALUES ('2017-11-29 07:27:24.000', '2017-11-29 09:44:33.000'),
('2017-11-29 11:57:37.000', '2017-11-29 12:05:39.000'),
('2017-11-29 15:12:31.000', '2017-11-29 17:24:32.000')
SELECT
FromTime = eah.InTime,
ToTime = eah.OutTime,
Message = 'Inside Office'
FROM @EmployeeAttendanceHours eah
UNION
SELECT
FromTime = eah.OutTime,
ToTime = eh.ToDateTime,
Message = 'Outside Office'
FROM @EmployeeDutyHours eh,@EmployeeAttendanceHours eah
WHERE eah.OutTime BETWEEN eh.FromDateTime AND eh.ToDateTime
UNION
SELECT
FromTime = eh.FromDateTime,
ToTime = eah.InTime,
Message = 'Outside Office'
FROM @EmployeeDutyHours eh, @EmployeeAttendanceHours eah
WHERE eah.InTime BETWEEN eh.FromDateTime AND eh.ToDateTime
ORDER BY 1, 2
我应该得到预期的结果?
**
修改
**
Below回答适用于上述情况而不适用于以下情况。
以下是员工的工作时间
案例#2
FromDateTime ToDateTime
---------------------------------------------------
2017-11-29 07:30:00.000 2017-11-29 12:30:00.000
2017-11-29 13:30:00.000 2017-11-29 16:30:00.000
以下是员工的出勤时间(办公时间内)
InTime OutTime
--------------------------------------------------------
2017-11-29 07:27:24.000 2017-11-29 09:44:33.000
2017-11-29 11:57:37.000 2017-11-29 12:05:39.000
2017-11-29 15:12:31.000 2017-11-29 17:24:32.000
预期内外时间与工作时间的关系应低于:
FromTime ToTime Remarks
-----------------------------------------------------------------------
2017-11-29 07:27:24.000 2017-11-29 09:44:33.000 Inside Office
2017-11-29 09:44:33.000 2017-11-29 11:57:37.000 Outside Office
2017-11-29 11:57:37.000 2017-11-29 12:05:39.000 Inside Office
2017-11-29 12:05:39.000 2017-11-29 12:30:00.000 Outside Office
2017-11-29 13:30:00.000 2017-11-29 15:12:31.000 Outside Office
2017-11-29 15:12:31.000 2017-11-29 17:24:32.000 Inside Office
但是我在应用this回答后得到了结果:
FromTime ToTime Remarks
-----------------------------------------------------------------------
2017-11-29 07:27:24.000 2017-11-29 09:44:33.000 Inside Office
2017-11-29 07:30:00.000 2017-11-29 11:57:37.000 Outside Office
2017-11-29 09:44:33.000 2017-11-29 12:30:00.000 Outside Office
2017-11-29 11:57:37.000 2017-11-29 12:05:39.000 Inside Office
2017-11-29 12:05:39.000 2017-11-29 12:30:00.000 Outside Office
2017-11-29 13:30:00.000 2017-11-29 15:12:31.000 Outside Office
2017-11-29 15:12:31.000 2017-11-29 17:24:32.000 Inside Office
答案 0 :(得分:0)
看看这个例子 - 我认为它解决了你想要完成的事情;但是,我不认为你的预期结果是完全准确的 - 我认为你错过了2017-12-11 07:30:00.000 - 2017-12-11 07:30:12.000的第一个“外部办公室”记录,因为员工技术上已经12秒钟了:
--DROP TABLE EmployeeDutyHours
CREATE TABLE EmployeeDutyHours
(
EmployeeId BIGINT,
ShiftFromTime DATETIME,
ShiftToTime DATETIME
)
INSERT INTO dbo.EmployeeDutyHours
VALUES (1, '2017-12-11 07:30:00.000', '2017-12-11 12:30:00.000'),
(1, '2017-12-11 15:30:00.000', '2017-12-11 18:30:00.000')
--DROP TABLE EmployeeAttendanceHours
CREATE TABLE EmployeeAttendanceHours
(
EmployeeId BIGINT,
InTime DATETIME,
OutTime DATETIME
)
INSERT INTO dbo.EmployeeAttendanceHours
VALUES (1, '2017-12-11 07:30:12.000', '2017-12-11 07:34:29.000'),
(1, '2017-12-11 12:45:28.000', '2017-12-11 13:04:15.000'),
(1, '2017-12-11 17:55:15.000', '2017-12-11 18:04:28.000')
SELECT
FromTime = eah.InTime,
ToTime = eah.OutTime,
Message = 'Inside Office'
FROM EmployeeAttendanceHours eah
UNION
SELECT
FromTime = eah.OutTime,
ToTime = eh.ShiftToTime,
Message = 'Outside Office'
FROM dbo.EmployeeDutyHours eh
JOIN dbo.EmployeeAttendanceHours eah ON eah.EmployeeId = eh.EmployeeId
WHERE eah.OutTime BETWEEN eh.ShiftFromTime AND eh.ShiftToTime
UNION
SELECT
FromTime = eh.ShiftFromTime,
ToTime = eah.InTime,
Message = 'Outside Office'
FROM dbo.EmployeeDutyHours eh
JOIN dbo.EmployeeAttendanceHours eah ON eah.EmployeeId = eh.EmployeeId
WHERE eah.InTime BETWEEN eh.ShiftFromTime AND eh.ShiftToTime
ORDER BY 1, 2
答案 1 :(得分:0)
我希望以下查询适合您。
DECLARE @EmployeeDutyHours TABLE (
FromDateTime datetime,
ToDateTime datetime
)
DECLARE @EmployeeAttendanceHours TABLE (
InTime datetime,
OutTime datetime
)
--INSERT INTO @EmployeeDutyHours VALUES ('2017-12-11 07:30:00.000', '2017-12-11 12:30:00.000'),('2017-12-11 15:30:00.000', '2017-12-11 18:30:00.000')
--INSERT INTO @EmployeeAttendanceHours VALUES ('2017-12-11 07:30:12.000', '2017-12-11 07:34:29.000'), ('2017-12-11 12:45:28.000', '2017-12-11 13:04:15.000'), ('2017-12-11 17:55:15.000', '2017-12-11 18:04:28.000')
INSERT INTO @EmployeeDutyHours VALUES ('2017-11-29 07:30:00.000', '2017-11-29 12:30:00.000'), ('2017-11-29 13:30:00.000', '2017-11-29 16:30:00.000')
INSERT INTO @EmployeeAttendanceHours VALUES ('2017-11-29 07:27:24.000', '2017-11-29 09:44:33.000'), ('2017-11-29 11:57:37.000', '2017-11-29 12:05:39.000'), ('2017-11-29 15:12:31.000', '2017-11-29 17:24:32.000')
;WITH CTE
AS (SELECT
*,
LEAD(InTime, 1) OVER (ORDER BY InTime) AS NextIn,
LEAD(OutTime, 1, '20491231') OVER (ORDER BY OutTime) AS NextOut,
LAG(InTime, 1) OVER (ORDER BY InTime) AS PrevIn,
LAG(OutTime, 1) OVER (ORDER BY OutTime) AS PrevOut
FROM @EmployeeAttendanceHours)
SELECT
a.InTime,
a.OutTime,
'Inside Office' AS Remarks
FROM CTE a
UNION
SELECT
a.OutTime,
NextIn,
'Outside Office'
FROM CTE a
CROSS APPLY (SELECT * FROM @EmployeeDutyHours WHERE (a.InTime < ToDateTime AND a.OutTime > FromDateTime) AND a.NextIn BETWEEN FromDateTime AND ToDateTime) d
UNION
SELECT
a.OutTime,
d.ToDateTime,
'Outside Office'
FROM CTE a
CROSS APPLY (SELECT * FROM @EmployeeDutyHours WHERE a.OutTime BETWEEN FromDateTime AND ToDateTime AND a.OutTime < ToDateTime AND (a.NextOut > ToDateTime)) d
UNION
SELECT
FromDateTime,
a.InTime,
'Outside Office'
FROM CTE a
CROSS APPLY (SELECT * FROM @EmployeeDutyHours WHERE a.InTime BETWEEN FromDateTime AND ToDateTime AND a.InTime > FromDateTime AND a.PrevOut NOT BETWEEN FromDateTime AND ToDateTime AND a.PrevIn IS NOT NULL) d
ORDER BY InTime, OutTime
评论案例#1并检查您的预期结果。
正如@ combatc2所说的那样,员工在#1的情况下技术上是12秒,如果你想要包含在结果中,请告诉我。