![](/img/trans.png)
[英]Trying to understand how to create a payroll query to condense clock ins and outs
[英]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.