更新前一行的记录

时间:2015-10-28 21:52:15

标签: sql-server insert-update

我遇到需要使用上一行值更新记录的情况。

来源:

MatID

此处3001(BaseID)和3001(FLAG)相同,因此BASEID = 1,在下一条记录中只有PKG1相同。输出应该|MatId | BaseId|Flag|Pkg1|CS1 ------------------------------ |3001 | 3001 | 1 | 20 | 2| |3002 | 3001 | 0 | 20 | 3| |3003 | 3001 | 0 | 20 | 4| 字段使用当前行值更新。

目标或输出:

{{1}}

如上面的目标所示,我必须使用第一个记录20中的值更新PKG1中的两个值。还有许多Pkg1列,如何使用单个查询更新所有列?

非常感谢任何帮助 感谢。

2 个答案:

答案 0 :(得分:2)

借助LEADLAG SQL Server中的函数获取上一个和下一个值非常简单。如果您使用的SQL Server早于2012版本且不支持LEADLAG功能,我们可以使用ROW_NUMBER()

尝试使用以下内容:

;WITH t AS
(
    select LAG(MatId) OVER (ORDER BY MatId) AS previousMatId
    ,      BaseId
    ,      MatId
    from   TABLE
)
update tab
set    tab.Pkg1 = p.Pkg1
from   TABLE tab
       inner join t on tab.MatId = t.MatId and t.BaseId = t.previousMatId
       left join (select MatId AS MatId 
                  ,     ISNULL(LAG(Pkg1) OVER (ORDER BY MatId), Pkg1) AS Pkg1
                  from TABLE) p on t.MatId = p.MatId

答案 1 :(得分:1)

您是否说需要使用属于原始垫子的Pkg1更新较新的垫子?如果是这样的话,那就是:

update NewMats
set NewMats.Pkg1 = Base.Pkg1
from MyTabe as NewMats
inner join (select BaseId, Pkg1
            from MyTable
            where BaseId = MatId) as Base
on Base.BaseId = NewMats.BaseId
where NewMats.BaseId < NewMats.MatId

但如果是这种情况,则需要更改数据模型。规则是给定的信息应该只存在于一个地方。所以也许可以把它分成两个相关的表。