簡體   English   中英

SQL 服務器:比較組中的行值並更新同一張表中的字段

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

我想根據StartDateEndDate為一組ID值更新 2 列EnrDrop

在附加的屏幕截圖中,例如ID = 82 ,我們有 2 行,因此必須比較 2 行。 第一行的結束日期(2013 年 12 月 13 日),下一行的if datediff(dy, Startdate, Enddate) > 30我必須將第 1 行中的列Drop更新為第 2 行中的 N 和Enr相應地傳遞給 Y。

對組中所有匹配的 id 執行相同的比較。 我想遍歷每組 ID 值並比較開始日期和結束日期,並基於該更新列 err 和 Drop。

在此處輸入圖像描述

請提供有關為此編寫查詢的最佳方式的輸入? 任何幫助是極大的贊賞。

謝謝斯威莎

嘗試使用CTEOUTER APPLY組合,如下所示:

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

注意:請確認 id 125StartDate ,這在更新之前和之后是不同的。

我希望它能解決你的問題

            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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM