Group Sequential SQL Records

て烟熏妆下的殇ゞ 提交于 2020-05-15 07:56:06

问题


Looking for a way to group sequential timeclock records into a single row.

The source system has an identity column, employee id, date and in/out flag (1=in & 2=out). Note that the

ID          EmployeeID    DATE                   InOut
1019374     5890          2008-08-19 14:07:14    1
1019495     5890          2008-08-19 18:17:08    2
1019504     5890          2008-08-19 18:50:40    1
1019601     5890          2008-08-19 22:06:18    2

I am looking for sql that would give me the following result

EmployeeID ClockIn             BreakStart          BreakEnd            ClockOut
5890       2008-08-19 14:07:14 2008-08-19 18:17:08 2008-08-19 18:50:40 2008-08-19 22:06:18

Note that the ID in the source system is not always sequential because of timeclock edits. Date should be chronological. If only two punches exist, I will need to have the clock in and clock out dates populated with no breaks (or something consistent that I can extract with a case statement). No breaks example below:

EmployeeID ClockIn             BreakStart          BreakEnd            ClockOut
5890       2008-08-19 14:07:14                                         2008-08-19 22:06:18

Sql version is 2008 R2

Thanks in advance, I can't figure out how to get this to work consistently and your help is greatly appreciated.


回答1:


You can do this with the ROW_NUMBER() function and a windowed COUNT() to handle the no break days:

;with cte as (SELECT *,ROW_NUMBER() OVER(PARTITION BY EmployeeID, CAST(dt AS DATE) ORDER BY dt) RN
                      ,COUNT(*) OVER(PARTITION BY EmployeeID, CAST(dt AS DATE)) Dt_CT
              FROM Table1)
SELECT EmployeeID
      ,Dt = CAST(dt AS DATE)
      ,ClockIn = MAX(CASE WHEN RN = 1 THEN DT END)
      ,BreakStart =  MAX(CASE WHEN Dt_CT = 4 AND RN = 2 THEN DT END)
      ,BreakEnd =  MAX(CASE WHEN Dt_CT = 4 AND RN = 3 THEN DT END)
      ,ClockOut = MAX(CASE WHEN (Dt_CT = 2 AND RN = 2) OR RN = 4 THEN DT END)
FROM cte
GROUP BY EmployeeID
        ,CAST(dt AS DATE)

Demo: SQL Fiddle

This is set by day, so a clockout after midnight wouldn't work, and odd number of punches would also be problematic, but for a simple world like your example this will do.



来源:https://stackoverflow.com/questions/25319075/group-sequential-sql-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!