Sql server 需要SQL查询5中的帮助吗

Sql server 需要SQL查询5中的帮助吗,sql-server,tsql,Sql Server,Tsql,我正在使用SQLServer2008。我有每个员工每天的数据。下面是示例数据 WITH RawData as ( SELECT '10001' AS EmpNo,'2015-01-01' as AttendanceDate,'FS' AS ShiftCode UNION SELECT '10001','2015-01-02','WO' UNION SELECT '10001','2015-01-03','FS' UNION SELECT '10001','2015-01-04','FS'

我正在使用SQLServer2008。我有每个员工每天的数据。下面是示例数据

WITH RawData as ( SELECT '10001' AS EmpNo,'2015-01-01' as AttendanceDate,'FS' AS ShiftCode UNION SELECT '10001','2015-01-02','WO' UNION SELECT '10001','2015-01-03','FS' UNION SELECT '10001','2015-01-04','FS' UNION SELECT '10001','2015-01-05','FS' UNION SELECT '10001','2015-01-06','FS' UNION SELECT '10001','2015-01-07','FS' UNION SELECT '10001','2015-01-08','FS' UNION SELECT '10001','2015-01-09','WO' UNION SELECT '10001','2015-01-10','FS' UNION SELECT '10001','2015-01-11','FS' UNION SELECT '10001','2015-01-12','FS' UNION SELECT '10001','2015-01-13','FS' UNION SELECT '10001','2015-01-14','FS' UNION SELECT '10001','2015-01-15','FS' UNION SELECT '10001','2015-01-16','WO' UNION SELECT '10001','2015-01-17','FS' UNION SELECT '10001','2015-01-18','FS' UNION SELECT '10001','2015-01-19','FS' UNION SELECT '10001','2015-01-20','FS' UNION SELECT '10001','2015-01-21','FS' UNION SELECT '10001','2015-01-22','FS' UNION SELECT '10001','2015-01-23','WO' UNION SELECT '10001','2015-01-24','FS' UNION SELECT '10001','2015-01-25','FS' UNION SELECT '10001','2015-01-26','FS' UNION SELECT '10001','2015-01-27','FS' UNION SELECT '10001','2015-01-28','FS' UNION SELECT '10001','2015-01-29','FS' UNION SELECT '10001','2015-01-30','WO' UNION SELECT '10001','2015-01-31','FS' UNION SELECT '10002','2015-01-01','FS' UNION SELECT '10002','2015-01-02','WO' UNION SELECT '10002','2015-01-03','WO' UNION SELECT '10002','2015-01-04','FS' UNION SELECT '10002','2015-01-05','FS' UNION SELECT '10002','2015-01-06','FS' UNION SELECT '10002','2015-01-07','FS' UNION SELECT '10002','2015-01-08','FS' UNION SELECT '10002','2015-01-09','WO' UNION SELECT '10002','2015-01-10','WO' UNION SELECT '10002','2015-01-11','FS' UNION SELECT '10002','2015-01-12','FS' UNION SELECT '10002','2015-01-13','FS' UNION SELECT '10002','2015-01-14','FS' UNION SELECT '10002','2015-01-15','FS' UNION SELECT '10002','2015-01-16','WO' UNION SELECT '10002','2015-01-17','WO' UNION SELECT '10002','2015-01-18','FS' UNION SELECT '10002','2015-01-19','FS' UNION SELECT '10002','2015-01-20','FS' UNION SELECT '10002','2015-01-21','FS' UNION SELECT '10002','2015-01-22','FS' UNION SELECT '10002','2015-01-23','WO' UNION SELECT '10002','2015-01-24','WO' UNION SELECT '10002','2015-01-25','FS' UNION SELECT '10002','2015-01-26','FS' UNION SELECT '10002','2015-01-27','FS' UNION SELECT '10002','2015-01-28','FS' UNION SELECT '10002','2015-01-29','FS' UNION SELECT '10002','2015-01-30','WO' UNION SELECT '10002','2015-01-31','WO') SELECT * FROM RawData Order By EmpNo,AttendanceDate 如何编写SQL查询以基于此示例数据获得以下输出?每个员工的工作周从每周休息后的一天开始,可以是周一、周二等任何一天。班次代码表示WO:每周休息,FS:第一班,SS:第二班

EmpNo WeekFrom WeekTo 10001 2015-01-01 2015-01-02 10001 2015-01-03 2015-01-09 10001 2015-01-10 2015-01-16 10001 2015-01-17 2015-01-23 10001 2015-01-24 2015-01-30 10001 2015-01-31 2015-01-31 10002 2015-01-01 2015-01-03 10002 2015-01-04 2015-01-10 10002 2015-01-11 2015-01-17 10002 2015-01-18 2015-01-24 10002 2015-01-25 2015-01-31 找到了解决办法。但在有100万行的实时表上花费了相当长的时间。我在查询中是否做错了什么?或者有更好的方法

WITH RawData as ( -- Insert above data here. ) ,ProcessData AS ( SELECT EmpNo,AttendanceDate,ShiftCode,RowID = ROW_NUMBER() OVER ( ORDER BY EmpNo, AttendanceDate ), WeekNo = 1 FROM RawData ) ,FinalData AS ( SELECT EmpNo, AttendanceDate, ShiftCode, RowID, WeekNo = 1 FROM ProcessData DA WHERE RowID = 1 UNION ALL SELECT DA.EmpNo, DA.AttendanceDate, DA.ShiftCode, DA.RowID, WeekNo = (CASE WHEN FinalData.EmpNo != DA.EmpNo THEN 1 ELSE FinalData.WeekNo + (CASE WHEN (FinalData.ShiftCode = 'WO' AND DA.ShiftCode != 'WO') THEN 1 ELSE 0 END) END) FROM FinalData INNER JOIN ProcessData DA ON DA.RowID = FinalData.RowID + 1 ) SELECT EmpNo, MIN(AttendanceDate) AS StartDate, MAX(AttendanceDate) AS EndDate, WeekNo FROM FinalData GROUP BY EmpNo, WeekNo ORDER BY EmpNo, WeekNo 试试这个:


这终于奏效了。23万条记录上5秒。我会继续我的解决方案。谢谢你抽出时间。希望这个解决方案能帮助别人

-- Step 1 : Save it to temp table SELECT EmpNo,AttendanceDate,ShiftCode,RowID = ROW_NUMBER() OVER ( ORDER BY EmpNo, AttendanceDate ), WeekNo = 1 into #RawData FROM -- My table -- Step 2 : Use temp table ;WITH FinalData AS ( SELECT EmpNo, AttendanceDate, ShiftCode, RowID, WeekNo = 1 FROM #RawData DA WHERE RowID = 1 UNION ALL SELECT DA.EmpNo, DA.AttendanceDate, DA.ShiftCode, DA.RowID, WeekNo = (CASE WHEN FinalData.EmpNo != DA.EmpNo THEN 1 ELSE FinalData.WeekNo + (CASE WHEN (FinalData.ShiftCode = 'WO' AND DA.ShiftCode != 'WO') THEN 1 ELSE 0 END) END) FROM FinalData INNER JOIN #RawData DA ON DA.RowID = FinalData.RowID + 1 ) SELECT EmpNo, MIN(AttendanceDate) AS StartDate, MAX(AttendanceDate) AS EndDate, WeekNo FROM FinalData GROUP BY EmpNo, WeekNo ORDER BY EmpNo, WeekNo OPTION (MAXRECURSION 0)
?以前从未问过问题,因此不了解规则。问题编辑并发布了我的解决方案。下次会小心的。@Habo,谢谢你的链接-员工10001在第一周缺少1天在第一周缺少2天,然后每周缺少1天。员工10001的最后一行,Weekto是2015-02-01,不在表中是;-。我们不能在查询中使用WO以外的硬编码移位码,因为它可以是任意的。e、 g.FS为第一班,SS为第二班,NS为夜班等。我们是否使用轮班代码“WO”?是的,你可以这样做。谢谢你的提示。上面说我只能在两天后接受。将在2天后尝试。我仍然不知道为什么在临时表中保存会将性能提高到如此程度。我假设这是所有排序,因为order by+row number需要很多时间,但是查看查询计划和统计io输出应该可以解释发生了什么 -- Step 1 : Save it to temp table SELECT EmpNo,AttendanceDate,ShiftCode,RowID = ROW_NUMBER() OVER ( ORDER BY EmpNo, AttendanceDate ), WeekNo = 1 into #RawData FROM -- My table -- Step 2 : Use temp table ;WITH FinalData AS ( SELECT EmpNo, AttendanceDate, ShiftCode, RowID, WeekNo = 1 FROM #RawData DA WHERE RowID = 1 UNION ALL SELECT DA.EmpNo, DA.AttendanceDate, DA.ShiftCode, DA.RowID, WeekNo = (CASE WHEN FinalData.EmpNo != DA.EmpNo THEN 1 ELSE FinalData.WeekNo + (CASE WHEN (FinalData.ShiftCode = 'WO' AND DA.ShiftCode != 'WO') THEN 1 ELSE 0 END) END) FROM FinalData INNER JOIN #RawData DA ON DA.RowID = FinalData.RowID + 1 ) SELECT EmpNo, MIN(AttendanceDate) AS StartDate, MAX(AttendanceDate) AS EndDate, WeekNo FROM FinalData GROUP BY EmpNo, WeekNo ORDER BY EmpNo, WeekNo OPTION (MAXRECURSION 0)