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

时间:2015-12-01 15:44:04

标签: sql sql-server sql-update

我有一个我似乎无法解决的SQL问题。

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

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

软件版本

  • ReleaseId(int)
  • ProductId(int)
  • 版本(int)
  • Status(int)// 0 = Old,1 = current,2 = future。

我们可以做的是创建一个选择以找出哪些记录不是最新版本...

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

但我们不能做的是对此进行适当更新状态字段的变体。这是我们需要实现的0(旧)和1(最新)。请注意,在运行脚本时,假定任何记录都是旧的或最新的。 “2”或未来的记录仅用于分期,不应予以考虑。

3 个答案:

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

答案 1 :(得分:1)

您可以使用ProductId分区上的Row_Number()函数执行此操作,然后根据它是否为最新版本更新Status列:

;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

答案 2 :(得分:0)

您可以将LEFT JOIN与表格一起使用,并检查交汇点的右侧是否为NULL

UPDATE SoftwareRelease SR
LEFT JOIN SoftwareRelease SR2 ON
  (SR.ProductId = SR2.ProductId And SR.Version > SR2.Version)
SET Status = Case When (SR2.ProductId is Null) Then 1 Else 0 End