--初次更新,方法1
declare @i int,@MaxID int
select @i = 1
select @MaxID = max(id) from @t
while @i <= @MaxID
begin
update a set a.AccValue = a.length + isnull(b.AccValue,0)
from @t a left join @t b on a.id = b.id + 1
where a.id = @i
set @i = @i + 1
end;--初次更新,方法2
select
id,
length,
AccValue=(select sum(length) from @t where id<=a.id)
from @t a
--================================================================
--2 当增加新记录时AccValue如果计算最合理有效
--3 当改动某条记录的length 后,受到影响的记录的AccValue如何计算最合理有效
----加一个触发器,在插入或更新时做以下操作
declare @iValueOrg int --记录用户修改前的值
declare @iValueMod int --记录用户修改后的值
declare @ID int --进行更新的记录ID
update @t set AccValue = AccValue + @iValueMod - @iValueOrg
where a.id >= @ID
length,
(select sum(length)
from @t b
where b.id < a.id) AccValue
from @t a
----加一个触发器,在插入或更新时做以下操作
declare @iValueOrg int --记录用户修改前的值
declare @iValueMod int --记录用户修改后的值
declare @ID int --进行更新的记录ID
update @t set AccValue = AccValue + @iValueMod - @iValueOrg
where a.id >= @ID
@iValueMod, @iValueOrg
两个变量的赋值过程就不写了
如果有为null的,置为0
insert @t(id,length)
select 1,10
union all select 2,30
union all select 3,40
union all select 4,70
union all select 5,90 select id,
length,
(select sum(length)
from @t b
where b.id <= a.id) AccValue
from @t a
1 10 10
2 30 40
3 40 80
4 70 150
5 90 240
insert @t(id,length)
select 1,10
union all select 2,30
union all select 3,40
union all select 4,70
union all select 5,90 select id,
length,
(select sum(length)
from @t b
where b.id <= a.id) AccValue
from @t a
/*
id length AccValue
----------- ----------- -----------
1 10 10
2 30 40
3 40 80
4 70 150
5 90 240
*/
returns bigint
as
begin
declare @ss bigint
select @ss=isnull(sum(length),0) from tsst where id<=@id
return @ss
end
go
create table tsst(id int,length int, AccValue as dbo.getts(id))
insert tsst(id,length)
select 1,10
union all select 2,30
union all select 3,40
union all select 4,70
union all select 5,90
insert @t(id,length)
select 1,10
union all select 2,30
union all select 3,40
union all select 4,70
union all select 5,90
1,更新方法
......
2 当增加新记录时AccValue如果计算最合理有效 ,
先得到最后一个 AccValue ,然后插入数据
declare @last_AccValue int
set @last_AccValue=(select top 1 AccValue from @t order by id desc)
insert into @t(length,AccValue) values(@length,@length+@last_AccValue)3、当改动某条记录的length 后,受到影响的记录的AccValue如何计算最合理有效
个人认为,这个时候,只有先更新一条记录,然后再用方法一,对ID>=更新ID 的记录全部进行重新计算
insert @t(id,length)
select 1,10
union all select 2,30
union all select 3,40
union all select 4,70
union all select 5,90
declare @c int,@c2 int
select @c=0
update @t set @c=@c+length,AccValue=@c
select * from @t
------------------
1 10 10
2 30 40
3 40 80
4 70 150
5 90 240
我认为这样更好
如果数据在上10万条呢?所以该问题的核心在于如何不重复累计已统计的信息。
下面是个人观点:
为已参与统计的数据加上处理标识。如果在10000中加上一条记录,那直接就以最后的值+新增记录。
如果在已有的记录中做修改,则直接在累计字段+增量。
如果不这样处理,再好的SQL语句,再优秀的表设计也枉然.
新增或修改记录时使用增量进行批量更新,我也是这么干对问题1有什么好的解决办法希望数据量在 <1W <10W <100W >100W 这几个区间时处理效率没有太明显差别