Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在T-SQL/MSSQL中再次通过数据进行CTE搜索?_Sql Server_Tsql_Common Table Expression_Recursive Query_Gaps And Islands - Fatal编程技术网

Sql server 如何在T-SQL/MSSQL中再次通过数据进行CTE搜索?

Sql server 如何在T-SQL/MSSQL中再次通过数据进行CTE搜索?,sql-server,tsql,common-table-expression,recursive-query,gaps-and-islands,Sql Server,Tsql,Common Table Expression,Recursive Query,Gaps And Islands,目前,我有一个员工时间条目列表,如下所示: TimeSheetId TechnicianUserId TimeSheetDate FromDatetime ToDatetime 1215286 4730 2020-11-10 2020-11-10 14:15:00.000 2020-11-10 15:15:00.000 1215965 4730 2020-11

目前,我有一个员工时间条目列表,如下所示:

TimeSheetId   TechnicianUserId    TimeSheetDate   FromDatetime              ToDatetime
    1215286               4730    2020-11-10      2020-11-10 14:15:00.000   2020-11-10 15:15:00.000
    1215965               4730    2020-11-10      2020-11-10 15:15:00.000   2020-11-10 15:45:00.000
    1215969               4730    2020-11-10      2020-11-10 15:45:00.000   2020-11-10 17:45:00.000
    1215972               4730    2020-11-10      2020-11-10 17:45:00.000   2020-11-10 23:45:00.000
    1215967               4730    2020-11-10      2020-11-10 23:45:00.000   2020-11-10 23:59:00.000
    1215968               4730    2020-11-11      2020-11-11 00:00:00.000   2020-11-11 00:15:00.000
    1215978               4730    2020-11-11      2020-11-11 00:15:00.000   2020-11-11 00:30:00.000
    1215980               4730    2020-11-11      2020-11-11 16:00:00.000   2020-11-11 16:30:00.000
    1215979               4735    2020-11-11      2020-11-11 00:30:00.000   2020-11-11 08:30:00.000
由于我们的时间是如何处理的,我希望第6行和第7行的时间表日期回滚一天,因为从技术上讲,它与前面的行是连续的时间,并且由我们的系统处理,因为所有的时间都发生在11月10日,而不是11月11日。不应在第7行或第9行不同员工编号之后立即回滚第8行

当我尝试嵌套查询时,我只捕获第6行。当我尝试一个没有时间表的CTE时,因为我不知道如何实现一种依赖它的方法,它不知道什么时候停止迭代并抛出。我如何确保我同时赶上第6行和第7行

我尝试过的CTE:

;WITH CTEDummyData (
                     [TechnicianUserId]
                    ,[TimeSheetDate]
                    ,[FromDatetime]
                    ,[ToDatetime]
                    )
AS (
SELECT [TechnicianUserId]
      ,[TimeSheetDate]
      ,[FromDatetime]
      ,[ToDatetime]
  FROM @DummyTime
 UNION ALL
SELECT [TechnicianUserId]
      ,CASE
            WHEN DATEDIFF(MINUTE,LAG([ToDateTime]) OVER (ORDER BY [FromDatetime]),[FromDatetime]) < 2
                    AND CAST([FromDatetime] AS DATE) <> LAG([TimeSheetDate]) OVER (ORDER BY [FromDatetime])
            THEN DATEADD(DAY,-1,[TimeSheetDate])
            ELSE [TimeSheetDate]
        END
      ,[FromDatetime]
      ,[ToDatetime]
  FROM CTEDummyData
    )
SELECT *
  FROM CTEDummyData
OPTION (MAXRECURSION 24)

我尝试了一个使用SQL循环的解决方案,在迭代中更新数据,直到它完全符合您的需要

DECLARE @NOMOREFORMATTINGNEEDED AS BIT = 0;
IF (EXISTS(SELECT * FROM SYS.tables WHERE name like '%TempDummyTimeTable%'))
BEGIN
    Drop table #TempDummyTimeTable;
END
SELECT * INTO #TempDummyTimeTable FROM DummyTimeTable;

WHILE (@NOMOREFORMATTINGNEEDED = 0)
BEGIN
    update tl set TimeSheetDate = t.TimeSheetDate from #TempDummyTimeTable tl 
                        join #TempDummyTimeTable t on   tl.TechnicianUserId = t.technicianuserid 
                        and ABS(DATEDIFF (MINUTE, tl.FromDatetime, t.ToDatetime)) <= 1
                        and tl.TimeSheetDate <> t.TimeSheetDate 

    IF (not exists(select * from #TempDummyTimeTable tl JOIN #TempDummyTimeTable t on   tl.TechnicianUserId = t.technicianuserid 
                        and ABS(DATEDIFF (MINUTE, tl.FromDatetime, t.ToDatetime)) <= 1
                        and tl.TimeSheetDate <> t.TimeSheetDate ) )
    BEGIN
        SET @NOMOREFORMATTINGNEEDED = 1
    END
END

select * from #TempDummyTimeTable
基本上,您可以在原始表的基础上创建一个新的临时表。 然后检查是否有任何行的实例与同一员工的另一行连续,但具有不同的时间表日期,然后更新该行的时间表日期。 在循环中继续执行此操作,直到@nomoreformatingneeded标志设置为true。将此标志设置为true的是一项检查,用于验证不再存在具有不同时间表日期的连续记录。我检查了一个的FromDateTime是否在另一个的ToDateTime的一分钟之内。
让我知道,如果这对你有用。< / P>只需双检查,行5和6被分类为连续的,尽管它们之间有一个完整的分钟,不像其他的结束和开始在同一时间。要添加到戴夫的评论,需要多少差距需要考虑2行附近作为不同的日期?您当前的系统/数据是否精确到最近的分钟?午夜是否有特殊处理,但您需要验证?有点奇怪,几乎所有行的时间都正好落在15分钟的边界上。@iamdave-由于午夜/白天的变化,系统强制执行这一分钟的差异。对于所有其他目的,应将其视为连续的。@SMor-是的,数据精确到最接近的分钟。技术人员使用的GUI将时间强制到最接近的分钟,并且时间通常为15秒,这就是数据看起来像这样的原因。如上所述,系统强制在晚上11:59到午夜之间留出一分钟来区分日历日。否则,时间被认为是连续的。顺便说一句,那一分钟的休息?我将创建一个视图,强制在下一个日期的23:59:00到00:00:00之间执行任何操作,这将修复UI条目的奇怪之处,并且应该为您的实际逻辑提供一个更理智的基础…这非常有效!非常感谢你!