有算法要求如下:
For (i=1,i<=10,i++) { ta[i] = (t[1] + t[2] + ... + t[i]) / i; }
用一條SQL語句實現它:
分別用表變量 @ta 和 @t 來對應 ta 和 t。
declare @t table(id int,d decimal(18,4)); declare @ta table(id int,da decimal(18,4)); insert into @t(id,d) values(1,1); insert into @t(id,d) values(2,2); insert into @t(id,d) values(3,3); insert into @t(id,d) values(4,4); insert into @t(id,d) values(5,5); insert into @t(id,d) values(6,6); insert into @t(id,d) values(7,7); insert into @t(id,d) values(8,8); insert into @t(id,d) values(9,9); insert into @t(id,d) values(10,10); insert into @ta(id,da) values(1,0); insert into @ta(id,da) values(2,0); insert into @ta(id,da) values(3,0); insert into @ta(id,da) values(4,0); insert into @ta(id,da) values(5,0); insert into @ta(id,da) values(6,0); insert into @ta(id,da) values(7,0); insert into @ta(id,da) values(8,0); insert into @ta(id,da) values(9,0); insert into @ta(id,da) values(10,0);
則有SQL語句:
with w(id,av) as( select a.id,avg(b.d) from @ta a,@t b where a.id>=b.id group by a.id ) update @ta set da=w.av from @ta a inner join w on a.id=w.id;
=================================================
但是這種方法有很嚴重的性能問題。后面記錄求前面所有記錄的平均值,每條記錄都要將前面的算一遍,而完全沒有辦法重用前面的計算結果,當列很多,記錄也很多的情況下,耗時非常的長。
這個時候,老老實實用游標,用循環來算,搞一些變量來保存中間值,性能反而很好。
真讓人感慨,都說SQL的強項不在循環,應該盡量用SQL語句來代替循環,但在這里,卻恰好相反。兵無常勢,水無常形,SQL的性能問題,也不是那么死板的。