簡體   English   中英

重疊上下班打卡的匯總打卡班次

[英]Summarized punch shifts for overlapping clock outs and ins

我有一個文件,其中包含每個員工的所有時間打卡班次,如下所示:

員工 開始時間 時間結束
123 2022-10-23 10:40:00.000 2022-10-23 14:00:00.000
123 2022-10-23 14:00:00.000 2022-10-23 14:30:00.000
123 2022-10-23 14:35:00.000 2022-10-23 17:07:00.000
541 2022-10-23 06:50:00.000 2022-10-23 12:00:00.000
541 2022-10-23 13:00:00.000 2022-10-23 15:30:00.000

但是,如果簽到和簽出在重疊的時間內,我想為每個員工返回一個匯總行

員工 開始時間 時間結束
123 2022-10-23 10:40:00.000 2022-10-23 17:07:00.000
541 2022-10-23 06:50:00.000 2022-10-23 12:00:00.000
541 2022-10-23 13:00:00.000 2022-10-23 15:30:00.000

我之所以要這樣做,是因為我將計算在給定時間段內屬於時班的員工。 現在我的查詢正在計算重復項,因為有員工在同一小時內打卡下班和打卡回來。

這是我計算每小時員工的代碼

WITH  Hours AS(
    SELECT 1 AS HOUR
    UNION ALL
    SELECT HOUR + 1 FROM Hours WHERE HOUR < 24
)
SELECT 
   CAST(Start_Time AS DATE) [DATE], 
   HOUR, 
   COUNT(Emp_Int) AS [Head Count]
FROM 
   Hours
LEFT JOIN 
   TIME_SHIFTS_TABLE T on HOUR BETWEEN DATEPART(HOUR, START_TIME) AND DATEPART(HOUR, END_TIME)
GROUP BY 
   CAST(Start_Time AS DATE), HOUR
ORDER BY 
   CAST(Start_Time AS DATE), HOUR asc

更新:接受的答案完美地解決了我的差距和孤島問題。 但是,此請求的最終目的是返回每個日期、每個小時的人數。 我遇到了一個問題,每當員工一天打卡並在第二天打卡時,我都無法獲得准確的計數。 下面是一個例子:

員工 開始時間 時間結束
799 2022-10-23 18:00:00.000 2022-10-23 18:30:00.000
799 2022-10-23 18:35:00.000 2022-10-24 10:30:00.000

接受的答案正確解決了差距並輸出以下內容

員工 開始時間 時間結束
799 2022-10-23 18:00:00.000 2022-10-24 10:30:00.000

但是,使用我現有的代碼(我相信這可能與我的 HOURS CTE 有關)output 沒有返回日期 2022-10-24 的人數

我當前的output如下(包括我最初問題中的記錄):

Date        Hour Count
2022-10-23  6   1
2022-10-23  7   1
2022-10-23  8   1
2022-10-23  9   1
2022-10-23  10  2
2022-10-23  11  2
2022-10-23  12  2
2022-10-23  13  2
2022-10-23  14  2
2022-10-23  15  2
2022-10-23  16  1
2022-10-23  17  1

這是完美的,但是,output 也應該像這樣返回第二天的人數:

Date        Hour Count
2022-10-24  1   1
2022-10-24  2   1
2022-10-24  3   1
2022-10-24  4   1
2022-10-24  5   1
2022-10-24  6   1
2022-10-24  7   1
2022-10-24  8   1
2022-10-24  9   1
2022-10-24  10  1

我已經包含了一個更新的演示

這是一個缺口和孤島問題。 處理此類任務的一種方法是

  • 首先用運行總和生成你需要的分區,
  • 然后使用MIN(start_time)MAX(end_time)應用聚合。

您可以通過以下方式制作運行總和:

  • 使用DATEDIFF檢查當前開始時間和上一個結束時間之間的差異何時大於 59 分鍾,因此如果是這種情況則用 1 標記
  • 在此標志上使用SUM window function,為您的每個員工

然后您可以在新創建的分區上運行聚合。

WITH cte AS (
    SELECT *,
           CASE WHEN DATEDIFF(mi, LAG(end_time) OVER(PARTITION BY employee ORDER BY start_time), start_time) >= 60 
                THEN 1 ELSE 0 
           END AS change_partition
    FROM tab
), cte2 AS (
    SELECT *, SUM(change_partition) OVER(PARTITION BY employee ORDER BY start_time) AS partitions
    FROM cte
)
SELECT employee, MIN(start_time) AS start_time, MAX(end_time) AS end_time 
FROM cte2
GROUP BY employee, partitions

此處查看演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM