简体   繁体   中英

SQL Server : compare row values in a group and update a field in the same table

I want to update 2 columns Enr and Drop based on StartDate and EndDate for a set of ID values.

In attached screenshot, example for ID = 82 , we have 2 rows so have to compare 2 rows. Enddate (12/13/2013) in first row with startDate (2/17/2014) in next row and if datediff(dy, Startdate, Enddate) > 30 I have to update the columns Drop in row1 to N and Enr in row2 to Y accordingly.

Perform the same comparison for all matching id's in the group. I want to iterate over each set of ID values and compare start and end dates and based on that update columns err and Drop.

在此处输入图像描述

Please provide inputs on best way to write query for this? Any help is greatly appreciated.

Thanks Swetha

Try this by using CTE and OUTER APPLY combination as below:

DECLARE @table TABLE(id INT, StartDate DATE, EndDate DATE, Enr CHAR(1), [Drop] CHAR(1))
INSERT INTO @table VALUES
(82,'2010-12-14','2013-12-13','Y','N'),
(82,'2014-02-17','2016-12-21','N','Y'),
(125,'2010-12-22','2015-06-23','Y','N'),
(125,'2015-06-23','2015-06-30','N','N'),
(125,'2015-08-16',NULL,'N','N'),
(555,'2010-12-28','2017-03-31','Y','N'),
(555,'2017-03-31',NULL,'N','N')


;WITH cte AS(
    SELECT t.*, 
        RANK() OVER(PARTITION BY id ORDER BY id, StartDate) rnk
    FROM @table t
)
UPDATE ta SET ta.[Drop] = CASE WHEN t1.Diff>30 THEN 'Y' ELSE ta.[Drop] END,
              ta.[Enr] = CASE WHEN t2.Diff>30 THEN 'Y' ELSE ta.[Enr] END
FROM cte t
INNER JOIN @table ta ON ta.id = t.id AND ta.StartDate = t.StartDate
OUTER APPLY(SELECT id, t1.StartDate, DATEDIFF(DAY,t.EndDate, t1.StartDate) Diff
            FROM cte t1
            WHERE t1.id = t.id
            AND t1.rnk = t.rnk+1) t1
OUTER APPLY(SELECT id, t.StartDate, DATEDIFF(DAY,t2.EndDate, t.StartDate) Diff
            FROM cte t2
            WHERE t2.id = t.id
            AND t2.rnk+1 = t.rnk) t2

OUTPUT:

id  StartDate   EndDate     Enr Drop
82  2010-12-14  2013-12-13  Y   Y
82  2014-02-17  2016-12-21  Y   Y
125 2010-12-22  2015-06-23  Y   N
125 2015-06-23  2015-06-30  N   Y
125 2015-08-16  NULL        Y   N
555 2010-12-28  2017-03-31  Y   N
555 2017-03-31  NULL        N   N

Note: Please confirm StartDate for id 125 , that is different in Before and After update.

I hope it will resolve your problem

            DECLARE @table TABLE(id INT, StartDate DATE, EndDate DATE, Enr CHAR(1), [Drop] CHAR(1))
            INSERT INTO @table VALUES
            (82,'2010-12-14','2013-12-13','Y','N'),
            (82,'2014-02-17','2016-12-21','N','Y'),
            (125,'2010-12-22','2015-06-23','Y','N'),
            (125,'2015-06-23','2015-06-30','N','N'),
            (125,'2015-08-16',NULL,'N','N'),
            (555,'2010-12-28','2017-03-31','Y','N'),
            (555,'2017-03-31',NULL,'N','N')

            select * from @table


            ;WITH cte AS(
                SELECT t.*, 
                    RANK() OVER(PARTITION BY id ORDER BY id, StartDate) rnk,
                    lead(StartDate,1)OVER (PARTITION BY id ORDER BY id, StartDate) as NextStartDate,
                    Lag(enddate,1)OVER (PARTITION BY id ORDER BY id, StartDate) as PrevEndDate

                FROM @table t
            )

            --select * from(
            --select *,DATEDIFF(DD,PrevEndDate,StartDate) q,DATEDIFF(DD,EndDate,NextStartDate) r,
            --case when (DATEDIFF(DD,PrevEndDate,StartDate) >30 and [Enr]='N') or [Enr]='Y' then 'Y' else 'N' end  newEnr,
            --case when (DATEDIFF(DD,EndDate,NextStartDate) >30 and [Drop]='N') or[Drop]='Y' then 'Y' else 'N' end newdrop 
            --from cte) as a


            update t
            set Enr=case when (DATEDIFF(DD,c.PrevEndDate,c.StartDate) >30 and c.[Enr]='N') or c.[Enr]='Y' then 'Y' else 'N' end,
            t.[Drop]=  case when (DATEDIFF(DD,c.EndDate,c.NextStartDate) >30 and c.[Drop]='N') or c.[Drop]='Y' then 'Y' else 'N' end
            from @table t
            inner join cte as c on t.id=c.id and t.StartDate=c.StartDate

            select * from @table

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM