组顺序SQL记录

时间:2014-08-14 23:20:00

标签: sql sql-server date time

寻找一种将顺序时钟记录分组到一行的方法。

源系统具有标识列,员工ID,日期和输入/输出标志(1 =& 2 = out)。注意

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

我正在寻找能给我以下结果的SQL

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

请注意,由于时钟编辑,源系统中的ID并不总是顺序的。日期应按时间顺序排列。如果只存在两个打孔,我将需要时钟输入和输出日期填充没有中断(或者我可以用case语句提取的一致性)。下面没有中断示例:

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

Sql版本是2008 R2

在此先感谢您,我无法弄清楚如何让这项工作始终如一,并且非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()功能和窗口COUNT()来处理无休息日:

;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)

演示:SQL Fiddle

这是按天设定的,所以午夜之后的时钟输出不起作用,奇数次的打孔也会有问题,但对于像你的例子这样的简单世界,这样做会有效。