How To check minimum Date in each observation and update flag dynamically

若如初见. 提交于 2019-12-06 05:40:36

Here is how I would approach it - there may be a recursive approach, but I don't use recursion unless it is absolutely necessary.

A couple of notes: I did the work in a temp table to make it easier to reset during development and testing, and I used an integer field for the flag to simplify the increment logic.

-- the setup
Create Table SO_Check_Min_Date
(
    ID Int
    , StartDate Date
    , EndDate Date
    , Flag Int
)

Insert Into dbo.SO_Check_Min_Date
(
    ID
    , StartDate
    , EndDate
)
Values
(1,     '2017-01-01',    '2017-02-01'),
(1,     '2017-01-09',    '2017-01-28'),
(1,     '2017-04-01',    '2017-04-30'),
(1,     '2017-04-05',    '2017-05-20'),
(1,     '2017-04-20',    '2017-06-12'),
(2,     '2017-06-02',    '2017-06-20'),
(2,     '2017-06-14',    '2017-07-31'),
(2,     '2017-06-14',    '2017-07-31'),
(2,     '2017-06-19',    '2017-07-31'),
(2,     '2017-06-19',    '2017-07-31')

-- the logic
Declare
@Flag As Int = 0
, @StartDate As Date
, @LookupDate As Date
, @ID As Int
, @PrevID As Int = 0;

Select
    *
Into
    #Temp_SO_Check
From SO_Check_Min_Date;

Select * From #Temp_SO_Check As tsc   -- to see that the flag field is blank

While Exists
(
    Select Top 1
                1
        From    #Temp_SO_Check
        Where   Flag Is Null
)
Begin
    Select Top 1
                @ID = ID
                , @StartDate = StartDate
        From    #Temp_SO_Check
        Where   Flag Is Null
        Order By
                ID
                , StartDate;

    If @PrevID <> @ID
        Begin
            Set @Flag = 1;
            Set @PrevID = @ID;
        End;
    Else
        Set @Flag = @Flag + 1;

    Set @LookupDate = DateAdd(Day, 30, @StartDate);

    Update
        #Temp_SO_Check
        Set
        Flag = @Flag
        Where
        ID = @ID
        And StartDate Between @StartDate
                    And     @LookupDate;
End;

Select * From #Temp_SO_Check As tsc      -- to see that it has been populated as desired

Since this is the original question--I'm posting the answer here. I'd suggest ditching your loops all together. Here's a way with 2 CTE's and ZERO loops.

declare @table table (ID int, StartDate date, EndDate date)
Insert Into @table
(
    ID
    , StartDate
    , EndDate
)
Values
(1,     '2017-01-01',    '2017-02-01'),
(1,     '2017-01-09',    '2017-01-28'),
(1,     '2017-04-01',    '2017-04-30'),
(1,     '2017-04-05',    '2017-05-20'),
(1,     '2017-04-20',    '2017-06-12'),
(2,     '2017-06-02',    '2017-06-20'),
(2,     '2017-06-14',    '2017-07-31'),
(2,     '2017-06-14',    '2017-07-31'),
(2,     '2017-06-19',    '2017-07-31'),
(2,     '2017-06-19',    '2017-07-31')


;with cte as(
select
    t1.ID
    ,t1.StartDate
    ,t1.EndDate
    ,DT = (select min(StartDate) from @table t2  where t2.StartDate > DATEADD(day,30,t1.StartDate))
from
    @table t1),

cte2 as(
select
    ID
    ,StartDate
    ,EndDate
    ,dense_rank() over (order by isnull(DT,(select max(StartDate) from cte))) as Flag
from
    cte)

select 
    ID
    ,StartDate
    ,EndDate
    ,case when Flag % 2 = 0 then 2 else Flag % 2 end as Flag
from cte2
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!