SQL Server 仅更新组中的最新记录

Posted

技术标签:

【中文标题】SQL Server 仅更新组中的最新记录【英文标题】:SQL Server Update Latest Records Only in a Group 【发布时间】:2018-07-26 21:43:56 【问题描述】:

我使用的是 SQL Server 2008 R2,我有 2 个表 ProductProduct_Master。我只想从Product 表中更新Product_Master 中最新版本的记录,而保留早期版本。

CREATE TABLE [dbo].[Product]
(
    [ProdId] [nvarchar](50) NOT NULL,
    [ProdDesc] [nvarchar](50) NULL,
    [ProdPrice] [decimal](18, 0) NULL,
    [Version] [int] NOT NULL
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Product_Master]
(
    [ProdId] [nvarchar](50) NOT NULL,
    [ProdDesc] [nvarchar](50) NULL,
    [ProdPrice] [decimal](18, 0) NULL,
    [Version] [int] NOT NULL
) ON [PRIMARY]
GO

INSERT INTO [dbo].[Product] ([ProdId], [ProdDesc], [ProdPrice], [Version]) 
VALUES (N'1001', N'Toys', CAST(2500 AS Decimal(18, 0)), 2),
       (N'1002', N'Books', CAST(1800 AS Decimal(18, 0)), 3)
GO

INSERT INTO [dbo].[Product_Master] ([ProdId], [ProdDesc], [ProdPrice], [Version]) 
VALUES (N'1001', N'Toys', CAST(2500 AS Decimal(18, 0)), 2),
       (N'1001', N'Toys', CAST(2000 AS Decimal(18, 0)), 1),
       (N'1002', N'Perfumes', CAST(1500 AS Decimal(18, 0)), 1),
       (N'1002', N'Perfumes', CAST(1500 AS Decimal(18, 0)), 2),
       (N'1002', N'Perfumes', CAST(1800 AS Decimal(18, 0)), 3)
GO

附上图片以便更好地理解。

enter image description here

【问题讨论】:

使用 CTE 选择您想要的记录,然后 UPDATE CTE。 【参考方案1】:

根据您共享的图像,可以在两个表之间使用简单的inner join 来更新主表中的价格。

Update PMT
SET PMT.ProdPrice = PT.ProdPrice
From prod_master_table PMT
INNER JOIN Product_Table PT On PT.ProdId = PMT.ProdId and PMT.Version = PT.Version 

【讨论】:

【参考方案2】:

我不确定您是否打算将Version 包含在您的Product 表中。如果你想匹配它们,这只是一个基于INNER JOIN 的简单UPDATE

您的问题似乎表明您想用Product 表中的内容更新最新记录。如果是这种情况,请使用 CTE 和 MERGE

; WITH cte (ProdID, ProdDesc, ProdPrice, Version) AS (
  SELECT ProdID, ProdDesc, ProdPrice, Version
  FROM (
    SELECT ProdID, ProdDesc, ProdPrice, Version
       , ROW_NUMBER() OVER (PARTITION BY ProdID ORDER BY Version DESC) AS rn 
    FROM Product_Master
  )s1
  WHERE rn= 1
)
MERGE INTO cte AS tgt
USING Product AS src
ON tgt.ProdID = src.ProdID
WHEN MATCHED
THEN
  UPDATE
  SET tgt.ProdPrice = src.ProdPrice
    , tgt.Version = src.Version
;

=========================================

编辑:OP 编辑​​应该是评论。

非常感谢您的努力和支持肖恩。很少的查询

Q1) 是否可以使用您的 CTE 创建存储过程?

A1) 我不明白为什么会这样。该代码可能是存储过程的理想选择。

Q2) 是否可以扩展您的 CTE 以更新多个表?

例如 Product 表有一些名为 Supplier Name 的附加列,是否可以在更新 Product_Master 的同时更新其他表中的这些列,例如 SupplierDetails?_

enter image description here

A2) 我在哪里看不到您的图片,所以我不知道它是否会在您的原始帖子中添加任何其他详细信息。根据您要执行的操作,您可以将其推送到同一个存储过程中或调用不同的存储过程进行修改。稍后我会尝试查看图像。

【讨论】:

非常感谢您的努力和支持肖恩。 @raajesh 对于您的其他问题,我不确定您要做什么。您可能不想从原始查询中更新两个不相关的表。您可能需要使用您正在尝试做的整个工作流程创建一个新问题。 MERGE 可以完成很多您正在寻找的事情,但它可能不是实现您最终目标的合适功能。 谢谢肖恩,第一季度我可以应付。关于第二季度。改变了要求,这就是为什么我不能更早地定义它。我很快就会给你表格的脚本。 Shawn 我在下面的链接上打开了一个新问题。请帮忙***.com/questions/51568137/…

以上是关于SQL Server 仅更新组中的最新记录的主要内容,如果未能解决你的问题,请参考以下文章

查询仅列出用户的最新记录

使用最大值 SQL 更新组中的所有行

使用 t-sql 仅加入“最新”记录

使用排序选择组中的最新记录

SQL Server 查找包含的组

分组并获取组中的最新记录[重复]