Sql 仅选择不在另一条记录的时间范围内开始的记录
我正在尝试使用MS SQL Server 2005实现以下目标,但不知道如何实现 目标是只选择与锚记录不在同一时间段内开始的记录 具有相同ID的行是一个组,并作为该组的一部分进行计算 从基于StartDate的最早日期A开始,与具有相同ID的下一行B进行比较 如果B在A内开始,则将B标记为无效。继续将A与具有相同ID的所有剩余记录进行比较。将A中的任何开始标记为无效 将不与重叠的下一条记录标记为有效记录。现在重复上述相同的过程,即检查是否有任何后续记录在新有效记录的时间范围内开始 重复此过程,直到分析完所有记录 示例:创建下表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中的任何开始标记为无效 将不与重叠的下一条记录标记为有效记录。现在重复上述相同的过程,即检查是否有任何后续记录在新有效记录的时间范围内开始 重复此过程,直
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时,我一定删除了一些预期的输出。谢谢你接电话。