2017-12-20 13 views
1

従業員が勤務時間内に社内外に何時間いるか調べたいと思います。以下は2つの異なるテーブルを比較して、不一致のタイムスタンプを確認してください

2つのテーブルの上に比較すると

CASE以下#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 

しかし、私は結果を取得しています:

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 

を私はDを取得する必要があります何を:私は私の質問をクリアし、下記の私は、この目的のために書いたクエリであると思います

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 

期待される結果は?

**

EDIT

**

Below答えは、上記のケースのために働いて、以下の場合のために働いていません。

以下

は、従業員のデューティ時間である

CASE以下第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

なぜFromTime 2017-12-11 07:34:29.000 ToTime 2017-12-11 12:30:00.000が外にありますか?それは従業員時間に合っていますか? – Wocugon

+0

'(FromTime、ToTime)' =(2017-12-11 12:45:28.000、2017-12-11 13:04:15.000)が期待される結果にリストされているのはなぜですか?この期間は従業員の勤務時間外です。 –

+0

@GiorgosBetsosが正しい。しかし、私は彼が社内にいるときの彼のすべてのタイミングを考えました。 –

答えて

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によれば、従業員は技術的に12秒間外出していました。結果に含める場合はお知らせください。

0

は、この例をチェックアウト - 私はそれはあなたが達成しようとしているものと思います解決。しかし、私はあなたの期待した結果が完全に正確だとは思わない - 2017-12-11 07:30:00.000 - 2017-12-11 07:30:12.000の "Outside office"従業員が技術的に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 
+0

あなたの答えはケース#1のために働いていますが、ケース#2のために失敗しました。確認して助けてください! –

関連する問題