【问题标题】:Update record with previous row用上一行更新记录
【发布时间】:2016-01-28 21:18:13
【问题描述】:

我有一种情况,我需要用前一行值更新记录。

来源:

|MatId | BaseId |Flag|Pkg1| CS1
--------------------------------
|3001  | 3001   | 1  | 20 | 2 |
|3002  | 3001   | 0  | 15 | 3 |
|3003  | 3001   | 0  | 10 | 4 |

这里 3001 (MatID) 和 3001(BaseID) 相同,所以 FLAG =1,在下一条记录中只有 BASEID 相同。输出应该只有 PKG1 字段更新为当前行值。

目标或输出:

|MatId | BaseId|Flag|Pkg1|CS1
------------------------------
|3001  | 3001  | 1  | 20 | 2|
|3002  | 3001  | 0  | 20 | 3|
|3003  | 3001  | 0  | 20 | 4|

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

非常感谢任何帮助。
谢谢。

【问题讨论】:

  • 您没有为您期望的上一行指定 ORDER。假设从您的示例中它是从 MatID 排序的。
  • 从BaseId升序排列
  • 如果BaseID = 以前的MatID,你想更新Pkg1,对吗?
  • @Megatron 是的,没错
  • 好的,MatId 是唯一的吗?

标签: sql-server insert-update


【解决方案1】:

在SQL Server 中借助LEADLAG 函数获取Previous 和Next 值非常简单。如果您使用的是比 2012 更早的 SQL Server 版本,它不支持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

【讨论】:

  • 谢谢你,我会尝试更新。查询 pkg1 中的一个问题设置为 999999,我希望它是上一个记录值。或者我在这里遗漏了一些东西。
  • 所以,当BaseID = 以前的MatID 时,您想将Pkg1 更新为以前的Pkg1。我说的对吗?
  • 是的,正确。当previous baseid = previous matid and current baseid = previous matid时,PKg1中的当前记录将更新为Pkg1中的先前记录
  • 我运行了您的查询并且它可以工作,但是当前记录变为 99999。我想像示例中一样获取上一个记录值 20。而且它只更新了一条记录,还有 2 条记录需要更新,值为 20,对查询进行哪些修改将有助于更新其他记录。
  • 好的,我会在几分钟内修改答案。请使用您问题上的编辑链接添加此附加信息
【解决方案2】:

您是说新的垫子需要使用属于原始垫子的 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

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

【讨论】:

  • 谢谢。您的查询有效,但仅适用于一条记录而不适用于两条记录。我需要根据第一条记录更新两条记录。
  • 好的,我结合了您的两个查询并得出了一些结论。它似乎适用于测试用例,将测试和更新你们。非常感谢您的帮助。我想我必须为其中包含 pkg 的每一列编写更新语句。
  • @Arun.K 在我看来,您应该有一个包含 pkg 的父表,然后是相关的子表,其中的内容因版本而异(MatId、CS1 等)。 )
猜你喜欢
  • 2020-11-26
  • 1970-01-01
  • 2020-12-11
  • 2019-02-18
  • 2020-07-19
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多