Sql 更新存在“较新”版本的记录

Sql 更新存在“较新”版本的记录,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,我有一个sql问题,似乎无法解决 请想象一个软件版本表。在该表中,我们有一个发布id、一个产品id、一个版本号和一个状态标志字段 请注意,我已经大大简化了这一点。在现实世界中,这是一个很大的表,因此我们引入了status以避免昂贵的分组查询,从而在结果中仅显示每个产品的最新版本等 软件发布 释放类整数 ProductId int 版本int 状态int//0=旧,1=当前,2=未来。 我们可以做的是创建一个select来找出哪些记录不是最新版本,所以 Select * From S

我有一个sql问题,似乎无法解决

请想象一个软件版本表。在该表中,我们有一个发布id、一个产品id、一个版本号和一个状态标志字段

请注意,我已经大大简化了这一点。在现实世界中,这是一个很大的表,因此我们引入了status以避免昂贵的分组查询,从而在结果中仅显示每个产品的最新版本等

软件发布 释放类整数 ProductId int 版本int 状态int//0=旧,1=当前,2=未来。 我们可以做的是创建一个select来找出哪些记录不是最新版本,所以

Select   * 
From     SoftwareRelease SR 
Where 
(
    Select   Count(*) 
    From     SoftwareRelease 
    Where    ProductId = SR.ProductId 
    And      Version > SR.Version
) > 0

但我们不能做的是在此基础上进行变体,以适当地更新状态字段。这就是我们需要为0岁和1岁以上的人实现的目标。注意:在运行脚本时,假定所有记录都是旧的或最新的。2或以后的记录仅用于暂存,不应考虑。

使用窗口功能如何

with toupdate as (
      select sr.*, row_number() over (partition by ProductId order by version desc) as seqnum
      from SoftwareRelease sr
     )
update toupdate
    set status = (case when seqnum = 1 then 1 else 0 end)
    where seqnum = 1 and status = 0 or seqnum > 1 and status <> 0;

使用窗口函数怎么样

with toupdate as (
      select sr.*, row_number() over (partition by ProductId order by version desc) as seqnum
      from SoftwareRelease sr
     )
update toupdate
    set status = (case when seqnum = 1 then 1 else 0 end)
    where seqnum = 1 and status = 0 or seqnum > 1 and status <> 0;
您可以通过ProductId分区上的Row_Number函数执行此操作,然后根据状态列是否为最新版本更新状态列:

;With Cte As
(
    Select  *,
            Row_Number() Over (Partition By ProductId Order By Version Desc) Row_Number
    From    SoftwareRelease
    Where   Status <> 2
)
Update  Cte
Set     Status = Case When Row_Number = 1 Then 1 Else 0 End
您可以通过ProductId分区上的Row_Number函数执行此操作,然后根据状态列是否为最新版本更新状态列:

;With Cte As
(
    Select  *,
            Row_Number() Over (Partition By ProductId Order By Version Desc) Row_Number
    From    SoftwareRelease
    Where   Status <> 2
)
Update  Cte
Set     Status = Case When Row_Number = 1 Then 1 Else 0 End
您可以对表使用LEFT JOIN来自检和检查连接的右侧是否为NULL

您可以对表使用LEFT JOIN来自检和检查连接的右侧是否为NULL


改为在存在的地方做,你会节省一些时间。改为在存在的地方做,你会节省一些时间。谢谢,这很有效。我现在正在分析它是如何工作的,以便从这次经历中学习。谢谢,这真的很有效。我现在正在分析它是如何工作的,以便从这次经历中学习。谢谢你。我接受了另一个答案,但这同样有效,值得感谢。谢谢你。我接受了另一个答案,但这同样有效,值得感谢。