2013-08-20 40 views
2

我有类似的查询:TSQL - 如何防止优化这个查询

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 

我不是特别在意性能,这是在几排

+0

我看到你发布了一个工程,你也可以显示你正在尝试工作的一个? –

+4

这是不可能的。这将是一个错误,如果是的话。 SQL Server会为[万圣节保护](http://blogs.msdn.com/b/craigfr/archive/2008/02/27/halloween-protection.aspx)的计划添加适当的操作符,以防止您想要的行为。 –

+0

@DennisJaheruddin什么?最上面的查询就是我想要做的工作。第二个以前在不同情况下工作 –

回答

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