2017-09-27 56 views
0

是的,SQL UPDATE可以与一起使用,作为SELECT的子查询。需要在子查询中订购的SQL更新

人在那里谁拥有了以下问题的解决方法:

不时程序在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在子查询中...

+0

您使用哪个dbms? – jarlh

+0

[如何更新来自其他表的顶部1的列]的可能的副本(https://stackoverflow.com/questions/6952277/how-to-update-the-column-coming-from-top-1-of -other-table) – Prisoner

+0

我们使用MS-SQL-Server 2012 –

回答

0

我改变了UPDATE -command到:

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可能会有很多变化,您只需要更改记录。

0

代替top 1使用ROW_NUMBER(),只保留行的地方是=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) 

您将应用的所有更新的所有记录,只有一个更新(注意< .. .some条件...>)