如何使用同一组中下一行的数据更新前一条记录

Posted

技术标签:

【中文标题】如何使用同一组中下一行的数据更新前一条记录【英文标题】:How to update preceding record with data from following row within same group 【发布时间】:2019-01-28 06:31:35 【问题描述】:

我有一组数据,我需要使用同一组内下一行中不同列的日期(较早的日期 - 如果存在)更新之前的记录日期列(较早的日期)。

我使用的是 SQL Server 2008 R2,因此无法使用 LEAD/LAG 函数。

更新前的数据:

ArticleId | DiscountStartDate   | DiscountEndDate     | Price
-------------------------------------
1         | 2018-08-10 23:59:59 | null                | 20    
1         | 2018-08-20 10:00:00 | null                | 30    
1         | 2019-01-10 01:00:00 | null                | 20
2         | 2018-11-10 12:00:00 | null                | 10    
1         | 2019-01-15 11:30:00 | null                | 21    
3         | 2018-05-10 12:00:00 | 2019-01-14 14:00:00 | 20    
3         | 2018-07-10 23:00:00 | 2019-01-14 14:00:00 | 10    
3         | 2019-01-10 12:00:00 | 2019-01-14 14:00:00 | 5    
4         | 2018-12-20 00:00:00 | 2019-01-19 14:00:00 | 20


CREATE TABLE [dbo].[ArticleDiscount](
[ArticleID] [int] NULL,
[DiscountStartDate] [datetime] NULL,
[DiscountEndDate] [datetime] NULL,
[Price] [money] NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[ArticleDiscount]
       ([ArticleID]
       ,[DiscountStartDate]
       ,[DiscountEndDate]
       ,[Price])
 VALUES
(1, '2018-08-10 23:59:59', null, 20),
(1, '2018-08-20 10:00:00', null, 30),
(1, '2019-01-10 01:00:00', null, 20),
(2, '2018-11-10 12:00:00', null, 10),
(1, '2019-01-15 11:30:00', null, 21),
(3, '2018-05-10 12:00:00', '2019-01-14 14:00:00' , 20),
(3, '2018-07-10 23:00:00', '2019-01-14 14:00:00' , 10),
(3, '2019-01-10 12:00:00', '2019-01-14 14:00:00' , 5),
(4, '2018-12-20 00:00:00', '2019-01-19 14:00:00' , 20) 

更新后的数据:

ArticleId | DiscountStartDate   | DiscountEndDate     | Price
-------------------------------------
1         | 2018-08-10 23:59:59 | 2018-08-20 10:00:00 | 20    
1         | 2018-08-20 10:00:00 | 2019-01-10 01:00:00 | 30    
1         | 2019-01-10 01:00:00 | 2019-01-15 11:30:00 | 20    
2         | 2018-11-10 12:00:00 | null                | 10    
1         | 2019-01-15 11:30:00 | null                | 21    
3         | 2018-05-10 12:00:00 | 2018-07-10 23:00:00 | 20    
3         | 2018-07-10 23:00:00 | 2019-01-10 12:00:00 | 10    
3         | 2019-01-10 12:00:00 | 2019-01-14 14:00:00 | 5    
4         | 2018-12-20 00:00:00 | 2019-01-19 14:00:00 | 20

编辑:基本上,如果特定 ArticleId 有较新的条目 (DiscountStartDate),我需要关闭该 ArticleID 的先前记录中的 DiscountEndDate。最新记录中的 DiscountEndDate 应保持不变(AtricleId 2,4,因为它们没有其他记录,ArticleId 1 和 3 的最新记录)并且记录中是否有空或某个日期无关紧要。

【问题讨论】:

`DiscountEndDate'的计算逻辑是什么? 另外,显示您的尝试代码 【参考方案1】:

要根据 articleid 更新日期,您可以尝试如下操作。

UPDATE t 
SET    DiscountEndDate = case when d.ddate is null then DiscountEndDate else d.ddate end
FROM   [ArticleDiscount] t 
       CROSS apply (SELECT Min(discountstartdate) ddate 
                    FROM   [ArticleDiscount] t1 
                    WHERE  t1.articleid = t.articleid 
                           AND t1.discountstartdate > t.discountstartdate)d 

Online Demo

【讨论】:

感谢您的帮助!不幸的是,articleid 3 和 4 的最后两行在更新后为空。 您是否没有根据 ArticleId 更新值,对于最后两行,它将为空,因为文章 id 的倒数第二条记录没有任何其他 id 为 3 的文章,4 也是如此 ArticleId=3 且 DiscountStartDate=2019-01-10 12:00:00 的最后一条记录是最新的,并且具有 DiscountEndDate - 此日期不应更新。 ArticleId=4 和 ArticleId=2 - 它们只有一条记录,它们也不应该被更新(保持不变) 我已经更新了分析器,请检查它现在应该可以工作 这太棒了!感谢您的帮助!【参考方案2】:

您也可以使用OUTER APPLYTOP 实现相同的效果,如下所示

UPDATE t SET t.DiscountEndDate = t1.DiscountStartDate
FROM #ArticleDiscount t
OUTER APPLY(SELECT TOP 1 DiscountStartDate
            FROM #ArticleDiscount t1
            WHERE t1.ArticleID = t.ArticleID 
            AND t1.DiscountStartDate > t.DiscountStartDate) t1
WHERE t1.DiscountStartDate IS NOT NULL

【讨论】:

以上是关于如何使用同一组中下一行的数据更新前一条记录的主要内容,如果未能解决你的问题,请参考以下文章

EXCEL VBA 窗体设计,如何实现查询前一条记录和后一条记录的功能。

如何解除物料的相互锁定

如何在同一个sql查询中更新和选择记录

当多个用户正在查看一条记录并且有1人更新该记录时,如何通知其他人该记录已更新?

多用户同时处理同一条数据解决办法

你如何让机器人在消息中下一行?