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

时间:2018-07-26 21:43:57

标签: sql sql-server sql-server-2008-r2 sql-update

我正在使用SQL Server 2008 R2,并且有2个表ProductProduct_Master。我只想更新Product_Master表中Product中记录的最新版本,而保持原样。

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

2 个答案:

答案 0 :(得分: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 

答案 1 :(得分:0)

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

您的问题似乎表明您想使用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编辑本应为注释。

非常感谢您的努力并支持Shawn。很少查询

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

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

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

例如,产品表具有一些名为“供应商名称”的附加列,是否可以在更新其他表(如“供应商详细信息”)时更新这些列?_

enter image description here

A2)我在哪里看不到您的图片,因此不知道它是否在您的原始帖子中添加了其他详细信息。根据您要尝试执行的操作,您可以将其推入相同的sproc或调用其他的sproc进行修改。稍后我会尝试查看图片。