2

我有一个类似于以下的查询:

update x
     set x.y = (
        select sum(x2.y)
        from mytable x2
        where x2.y < x.y
     )
from mytable x

关键是,我正在遍历行并基于对那些正在更改的字段的子查询更新字段。

我看到的是在发生任何更新之前正在为每一行执行子查询,因此不会获取每行的更改值。

如何强制为更新的每一行重新评估子查询?

是否有合适的表格提示或其他内容?

顺便说一句,我正在执行以下操作并且确实有效,但是由于稍微修改了我的查询(出于逻辑目的,而不是尝试解决此问题),此技巧不再有效:​​(

declare @temp int
update x
     set @temp = (
        select sum(x2.y)
        from mytable x2
        where x2.y < x.y
     ),
     x.y = @temp
from mytable x

我不是特别关心性能,这是一个运行几行的后台任务

4

1 回答 1

0

看起来任务不正确或应该应用其他规则。

让我们看一个例子。假设您有值4, 1, 2, 3, 1, 2

Sql 将根据原始值更新行。即在单个更新语句期间,新计算的值不与原始值混合:

--  only original values used
4 -> 9     (1+2+3+1+2)
1 -> null
2 -> 2     (1+1)
3 -> 6     (1+2+1+2)
1 -> null
2 -> 2     (1+1)

根据您的请求,您希望每行的更新将计算新计算的值。(注意,SQL 不保证处理行的顺序。) 让我们通过从上到下处理行来做这个计算:

--  from top
4 -> 9    (1+2+3+1+2)
1 -> null
2 -> 1    (1)
3 -> 4    (1+1+2)
1 -> null
2 -> 1    (1)

在其他顺序中执行相同操作 - 从下到上:

--  from bottom
4 -> 3    (2+1)
1 -> null 
2 -> 1    (1)
3 -> 5    (2+2+1)
1 -> null
2 -> 2    (1+1)

你如何看到你的预期结果是不一致的。为了使它正确,您需要更正计算规则 - 例如定义要处理的行的强序列(日期,id,...)此外,如果您想做一些递归处理,请查看common_table_expression

http://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

于 2013-09-03T19:45:52.537 回答