我不确定我是否理解正确:相同的员工,相同的任务,每天输入相同的小时数(连续 - 不包括周末)。
但是您描述的逻辑也会选择行:7 和 8
7 1000 T3 2015-01-09 5 0
8 1000 T3 2015-01-12 5 0
相同的员工1000
相同的任务T3
相同的小时数5
,2015-01-09
是星期五和2015-01-12
星期一,所以天是连续的(周末除外)
考虑到我在这里得到的是 MS SQL 2008 实现:
WITH EHT AS (
SELECT [ROW]
,[EMP_NO]
,[TASK]
,[DATE]
,[HOURS]
,DATEPART(DW,[DATE]) AS DayWeek /* Sunday = 1 */
,ROW_NUMBER() OVER (PARTITION BY [EMP_NO],[TASK] ORDER BY [DATE]) AS DT_RNK
FROM [EMP_HOUR_LOG]
)
SELECT
A1.*
,A2.[DATE] AS Next_Date
,A3.[DATE] AS Previous_Date
,CASE /* for Next Date logic*/
WHEN A2.DayWeek<>2 /*Tuesday to Friday*/
AND DATEDIFF(DD, A1.[DATE], A2.[DATE]) = 1
THEN 1
WHEN A2.DayWeek=2 /*Monday*/
AND DATEDIFF(DD, A1.[DATE], A2.[DATE]) = 3 /* 3 days from Friday to Monday*/
Then 1
/* for Previous Date logic*/
WHEN A2.[DATE] IS NULL
AND A3.DayWeek=6 /* Friday */
AND DATEDIFF(DD, A3.[DATE], A1.[DATE]) = 3 /* 3 days from Friday to Monday*/
THEN 1
WHEN A2.[DATE] IS NULL
AND A3.DayWeek<>6 /* Mon to Thur */
AND DATEDIFF(DD, A3.[DATE], A1.[DATE]) = 1
Then 1
ELSE 0 END
AS FLAG
FROM EHT AS A1
LEFT JOIN EHT AS A2
ON (A1.[EMP_NO]=A2.[EMP_NO]
AND A1.[TASK]=A2.[TASK]
AND A1.[HOURS]=A2.[HOURS]
AND A1.DT_RNK=A2.DT_RNK-1)
LEFT JOIN EHT AS A3
ON (A1.[EMP_NO]=A3.[EMP_NO]
AND A1.[TASK]=A3.[TASK]
AND A1.[HOURS]=A3.[HOURS]
AND A1.DT_RNK=A3.DT_RNK+1)
首先使用 Weekday 函数创建临时表 EHT 来识别一天是周六还是周日 (7,1)。从 1...n 添加订单号(Rwo_number 函数),在员工、任务和订购日期从最低到最高重置。
然后在第二步中将 EHT 表左连接到自身。使用 Emp、Task 和 hour 列(排除 emp、task 和 hours 不匹配的所有情况)+ 将第二个表向后移动 1 个 Order num ( A1.DT_RNK=A2.DT_RNK-1
)。有了它,我就能够识别系列中的下一个数据。
但是,系列中的最后一个日期没有下一个日期,因为它是最后一个。我需要从头到尾识别系列。因此,我将再次加入表格,但这次,将表格向前移动 1 个订单号 ( A1.DT_RNK=A2.DT_RNK+1
) 以识别系列中的上一个日期。
现在的逻辑只是计算日期和下一个日期或日期和上一个日期之间的天数,如果等于 1,那么它们是连续的。对于星期一日期,它必须是 3。同样,当考虑到意甲中没有下一个日期的最后一个条目时,如果是星期五,我们需要检查上一个日期,那么它也必须等于 3。
可能有更简单的解决方案。但这是有效的。仍然像上面提到的 Gordon Linoff 一样,您没有将第 7 行和第 8 行包含在 FLAG = 1 中。我的逻辑包括它们,因为它是从星期五到星期一的连续日期。也许您正在考虑其他一些假期。
结果详情:
