Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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 仅选择不在另一条记录的时间范围内开始的记录_Sql_Date_Sql Server 2005 - Fatal编程技术网

Sql 仅选择不在另一条记录的时间范围内开始的记录

Sql 仅选择不在另一条记录的时间范围内开始的记录,sql,date,sql-server-2005,Sql,Date,Sql Server 2005,我正在尝试使用MS SQL Server 2005实现以下目标,但不知道如何实现 目标是只选择与锚记录不在同一时间段内开始的记录 具有相同ID的行是一个组,并作为该组的一部分进行计算 从基于StartDate的最早日期A开始,与具有相同ID的下一行B进行比较 如果B在A内开始,则将B标记为无效。继续将A与具有相同ID的所有剩余记录进行比较。将A中的任何开始标记为无效 将不与重叠的下一条记录标记为有效记录。现在重复上述相同的过程,即检查是否有任何后续记录在新有效记录的时间范围内开始 重复此过程,直

我正在尝试使用MS SQL Server 2005实现以下目标,但不知道如何实现

目标是只选择与锚记录不在同一时间段内开始的记录

具有相同ID的行是一个组,并作为该组的一部分进行计算

从基于StartDate的最早日期A开始,与具有相同ID的下一行B进行比较

如果B在A内开始,则将B标记为无效。继续将A与具有相同ID的所有剩余记录进行比较。将A中的任何开始标记为无效

将不与重叠的下一条记录标记为有效记录。现在重复上述相同的过程,即检查是否有任何后续记录在新有效记录的时间范围内开始

重复此过程,直到分析完所有记录

示例:创建下表

if object_id ('tempdb..#Dates') is not null drop table #Dates

create table #Dates (ID int, StartDate datetime, EndDate datetime)
Insert into #Dates
Select 1, '7/23/2003'   ,   '8/22/2003'  union all
select 1, '8/21/2003'   ,   '11/19/2003' union all
select 1, '11/18/2003'  ,   '12/18/2003' union all
select 1, '12/17/2003'  ,   '1/16/2004'  union all
select 1, '1/15/2004'   ,   '2/14/2004'  union all
select 1, '2/11/2004'   ,   '2/26/2004'  union all
select 1, '9/14/2004'   ,   '10/14/2004' union all
select 1, '10/5/2004'   ,   '10/20/2004' union all
select 1, '11/20/2004'  ,   '12/20/2004' union all
select 1, '12/19/2004'  ,   '1/18/2005'  union all
select 1, '1/12/2005'   ,   '1/27/2005'  union all
select 1, '2/27/2005'   ,   '3/11/2005'  
应用重叠逻辑规则后的预期输出:

ID StartDate EndDate Valid -- --------- --------- ----- 1 7/23/2003 8/22/2003 1 1 8/21/2003 11/19/2003 0 1 11/18/2003 12/18/2003 1 1 12/17/2003 1/16/2004 0 1 1/15/2004 2/14/2004 1 1 2/11/2004 2/26/2004 0 1 9/14/2004 10/14/2004 1 1 10/5/2004 10/20/2004 0 1 11/20/2004 12/20/2004 1 1 12/19/2004 1/18/2005 0 1 1/12/2005 1/27/2005 1 1 2/27/2005 3/11/2005 1
我想出了如何回答我自己的问题。使用行号对记录排序后使用递归SQL

if object_id ('tempdb..#Dates') is not null drop table #Dates

create table #Dates (ID int, StartDate datetime, EndDate datetime)
Insert into #Dates
Select 1, '7/23/2003'   ,   '8/22/2003'  union all
select 1, '8/21/2003'   ,   '11/19/2003' union all
select 1, '11/18/2003'  ,   '12/18/2003' union all
select 1, '12/19/2004'  ,   '1/18/2005'  union all
select 1, '1/12/2005'   ,   '1/27/2005'  union all
select 1, '2/27/2005'   ,   '3/11/2005'  union all
select 1, '12/17/2003'  ,   '1/16/2004'  union all
select 1, '1/15/2004'   ,   '2/14/2004'  union all
select 1, '2/11/2004'   ,   '2/26/2004'  union all
select 1, '9/14/2004'   ,   '10/14/2004' union all
select 1, '10/5/2004'   ,   '10/20/2004' union all
select 1, '11/20/2004'  ,   '12/20/2004'


--Phase 1:  Apply ordering to dates
if object_id ('tempdb..#OrderedRecords') is not null drop table #OrderedRecords 

select *, N = row_number () over (partition by ID order by StartDate asc, EndDate desc)
into #OrderedRecords
from #Dates


--Phase 2:  Apply Overlap Rules (Subsume records that overlap)    
;with Subsume (ID, N, StartDate, EndDate, IntermediateStartDate, IntermediateEndDate, Valid) as
(
    select  ID, N, StartDate, EndDate, IntermediateStartDate = StartDate, IntermediateEndDate = EndDate,         
            Valid = 1
    from    #OrderedRecords 
    where   N = 1
    UNION ALL   
    select  c.ID, c.N, y.StartDate, y.EndDate,
            IntermediateStartDate = case when c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate then y.IntermediateStartDate else c.StartDate end, 
            IntermediateEndDate  = case when c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate then y.IntermediateEndDate else c.EndDate end,               
            Valid = case when (c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate) then 0 else 1 end
    from    #OrderedRecords c
    join    Subsume y
            on  y.ID = c.ID
            and y.N = c.n - 1
            and y.IntermediateStartDate >= c.EndDate
    UNION ALL   
    select  c.ID, c.N, c.StartDate, c.EndDate,
            IntermediateStartDate = case when c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate then y.IntermediateStartDate else c.StartDate end, 
            IntermediateEndDate  = case when c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate then y.IntermediateEndDate else c.EndDate end,
            Valid = case when (c.StartDate between y.IntermediateStartDate and y.IntermediateEndDate) then 0 else 1 end
    from    #OrderedRecords c
    join    Subsume y
            on  y.ID = c.ID
            and y.N = c.n - 1
            and y.IntermediateStartDate < c.EndDate
)

Select ID, StartDate, EndDate, Valid
from Subsume
OPTION (MAXRECURSION 0)

*请注意,在这个网站上,您可以询问有关特定编程问题的问题。这只是一个任务要求,没有明显的问题。发布您迄今为止为实现这一目标而编写的任何代码。哪种SQL风格?我正试图实现所述目标,但不知道如何实现。我正在使用MS SQL Server 2005。我曾尝试过使用一些递归,但不幸的是,它与我试图实现的目标相差甚远。我真的没有任何有用的代码可以发布,因为我不知道如何解决这个问题。您的示例结果与描述不符。例如,第二行之前没有结束日期,所以它应该在输出中。是的,Gordon,你是对的,我花了很长时间试图获得正确粘贴的预期结果。我想我现在是对的。在编辑HTML时,我一定删除了一些预期的输出。谢谢你接电话。