【问题标题】:SQL Update with need to order in subquery需要在子查询中排序的 SQL 更新
【发布时间】:2017-09-27 07:15:23
【问题描述】:

是的,SQL UPDATE 可以在SELECT-子查询中与order by 一起使用。

任何有解决以下问题的方法的人:

程序有时会在TABLE1 中生成数据错误(我们不是该代码的所有者,但需要使用该程序...)

我们使用一个触发器来处理对AUDIT 表的所有更改。

我们可以通过以下选择找到错误情况(以及正确的旧值):

select top 1 audit.OldValue 
     from TABLE1
     left join AUDIT on AUDIT.Table1_ID = TABLE1.ID
where <...some conditions...>
   order by AUDIT.UpdateDate desc

由于记录了多项更改,我们只需要最后一次更改(order by updatedate 然后采用TOP 1

如果我们可以使用UPDATE 命令,我们会更正数据错误

Update TABLE1
set VALUE = 
( select top 1 audit.OldValue
    from TABLE1
    left join AUDIT on AUDIT.Table1_ID = TABLE1.ID
  where <...some conditions...>
    order by AUDIT.UpdateDate desc )
where TABLE1.ID = AUDIT.Table1_ID

但是:您不能在子查询中使用order by...

【问题讨论】:

  • 您使用的是哪个 dbms?
  • 我们使用 MS-SQL-Server 2012
  • 这种限制似乎没有意义。您是否认为您不能在子查询中使用ORDER BY,或者您是否尝试过这样的错误消息?
  • 尝试使用 CTE 而不是子查询

标签: sql sql-server sql-server-2012 sql-update sql-order-by


【解决方案1】:

使用ROW_NUMBER() 代替top 1 并仅保留=1 所在的行

类似:

Update t set Value = A.OldValue
FROM Table1 t
inner join (
    select ROW_NUMBER() OVER (PARTITION BY UserCode ORDER BY MEASUREDATE DESC) N, Id Table1_ID, *
    from AUDIT
) a on a.Table1_ID = t.ID
where <...some conditions...>
AND (a.N=1)

您将对所有记录应用所有更新,只需一次更新(注意<...>)

【讨论】:

    【解决方案2】:

    我将UPDATE-命令更改为:

    Update TABLE1
    set VALUE = CORRECT_VALUES.OldValue
    from
    ( select top 1 audit.OldValue OldValue, AUDIT.Table1_ID Table1_ID
        from TABLE1
        left join AUDIT on AUDIT.Table1_ID = TABLE1.ID
      where <...some conditions...>
        order by AUDIT.UpdateDate desc ) as CORRECT_VALUES
    where TABLE1.ID = CORRECT_VALUES.Table1_ID
    

    效果很好。

    由于这只改变了 1 个条目(由于 TOP 1),我们必须使用循环:

    Declare @i int = 0
    Declare @NUMBER int = (select count(*) from 
       (select distinct AUDIT.Table1_ID 
           from TABLE1
           left join AUDIT on AUDIT.Table1_ID = TABLE1.ID
        where <...some conditions...>
       ) )
    
    while @i < @NUMBER
    BEGIN
       SET @i = @i + 1
       <... past the whole UPDATE command here ...>
    END
    

    适用于所有需要更新的记录。

    注意distict,因为同一个ID可能会有很多变化,你只需要改变记录。

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多