如何在连续日期的记录中查找日期范围?

时间:2011-03-15 20:26:51

标签: sql sql-server sql-server-2005 tsql

我有一个包含数据的表:

ID    StartDate    EndDate     EffectiveDate
--    ---------    -------     -------------
1     1/1/2009     12/31/2009    12/31/2009
1     7/1/2009     12/31/2009    7/1/2009
1     8/1/2009     12/31/2009    8/1/2009
2     1/1/2010     12/31/2010    12/31/2010
2     3/1/2010     12/31/2010    12/31/2010

我需要一个像这样格式化的查询,但是:

ID    StartDate    EndDate     EffectiveDate
--    ---------    -------     -------------
1     1/1/2009     6/30/2009    null
1     7/1/2009     7/31/2009    7/1/2009
1     8/1/2009     12/31/2009   8/1/2009
2     1/1/2010     2/28/2010    null
2     3/1/2010     12/31/2010   12/31/2010
...

它基本上就像一个带有分段“点”的时间轴,每个点都是一个新的StartDate,其EndDate是下一个点,依此类推。

我尝试过使用CTE,以及以下查询:

   SELECT t1.RfqItemOptionId, 
          t1.StartDate, 
          MIN(t2.EffectiveDate) EndDate,  
          t1.EffectiveDate EffectiveDate
     FROM @OptionPeriods t1 
LEFT JOIN @OptionPeriods t2 ON t1.RfqItemOptionId = t2.RfqItemOptionId
                           AND t1.EffectiveDate < t2.EffectiveDate
 GROUP BY t1.RfqItemOptionId, t1.StartDate, t1.EffectiveDate

哪个很近......但没有雪茄:(

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

;With Base As
(
    Select
          *
        , ROW_NUMBER() Over (Partition By ID Order By StartDate) RowNum
    From
        @OptionPeriods
)
Select
      B1.*
    , IsNull(B2.StartDate - 1, B1.EndDate) As NewEndDate
    , Case B1.RowNum When 1 then Null Else B1.StartDate End As NewEffectiveDate
From
    Base B1
Left Join
    Base B2
On
    B1.ID = B2.ID
    AND
    B1.RowNum + 1 = B2.RowNum

答案 1 :(得分:0)

我是一个oracle人,这里是SQL的oracle版本.... 请用相应的SQL-Server SQL替换相关的分析SQL ...

SELECT id, 
       startdate,
       enddate,
       case WHEN enddate < effectivedate THEN null ELSE effectivedate end AS effectivedate
FROM (
    SELECT id, 
           startdate,
           nvl2(next_startdate,(next_startdate-1),enddate) enddate,
           effectivedate
    FROM (
        SELECT a.*,
               lead(startdate,1) over (partition by id order by id,startdate) next_startdate
        FROM tblTest a
        ORDER BY 1,2
    )
);

谢谢, Venkat