[英]SQL Server : compare row values in a group and update a field in the same table
我想根據StartDate
和EndDate
為一組ID
值更新 2 列Enr
和Drop
。
在附加的屏幕截圖中,例如ID = 82
,我們有 2 行,因此必須比較 2 行。 第一行的結束日期(2013 年 12 月 13 日),下一行的if datediff(dy, Startdate, Enddate) > 30
我必須將第 1 行中的列Drop
更新為第 2 行中的 N 和Enr
相應地傳遞給 Y。
對組中所有匹配的 id 執行相同的比較。 我想遍歷每組 ID 值並比較開始日期和結束日期,並基於該更新列 err 和 Drop。
請提供有關為此編寫查詢的最佳方式的輸入? 任何幫助是極大的贊賞。
謝謝斯威莎
嘗試使用CTE
和OUTER 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 125的StartDate
,這在更新之前和之后是不同的。
我希望它能解決你的問題
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.