一个循环算法的问题 长长的标题 请大家帮忙~~~ 谢谢

tojht 2009-10-27 10:43:12
表tb
id yc ym begin end month code
101 100.00 120.00 150.00 130.00 1 1
101 130.00 30.00 130.00 230.00 2 1
501 1 2 5 4 1 1
501 2 3 4 3 2 1
501 5 7 12 10 1 9999
20201 13 12 10 9 1 1100



就是这样一个余额表 除了1月的Begin已经有数据外 其他月的BEGIN 都等于上一个月的END 例如 2月的BEGIN=1月的END , 而 以1开头或者5开头的ID 他的END =BEGIN +YC - YM ,2 3 4开头的ID 他的END = BEGIN +YM-YC 每条数据都有12个月 。。。 算出所有数据的BEGIN 和END。。。。(CODE是上一级的单位 编号可能相同 但是上一级单位不同)

这是我写的算法 要循环9999次 好慢呀 !!!!
DECLARE @code INT,
@id varchar(100),
@begin numeric(18,2),
@mon int
set @mon=1
SET @code=1
WHILE (@code<=9999)
begin
DECLARE A1 CURSOR FOR
SELECT id FROM tb WHERE code=@code GROUP BY id
OPEN A1
FETCH NEXT FROM A1 INTO @id
WHILE @@FETCH_STATUS=0
begin

while @mon<=12
BEGIN
if(@id like '1%' or @id like '5%')
begin
select @begin=isnull(begin,0)+isnull(yc,0)-isnull(ym,0) from tb where id=@id and code=@code and month=@mon
update tb set end=@begin where id=@id and code=@code and month=@mon
update tb set begin=@begin where month=@mon+1 and code=@code and id=@id
set @begin=0
set @mon=@mon+1
end
else
begin
select @begin=isnull(begin,0)+isnull(ym,0)-isnull(yc,0) from tb where id=@id and code=@code and month=@mon
update tb set end=@begin where month=@mon and code=@code and id=@id
update aly_accsum set mbeginbal=@begin where month=@mon+1 and code=@code and id=@id
set @ycye=0
set @mon=@mon+1
end

END

FETCH NEXT FROM A1 INTO @id
set @mon=1
end
close A1
deallocate A1
set @code=@code+1
end


所以 请教高手 怎么写才快一些? 我是新人 如果可以的话 把您写的代码 加上一些注释 谢谢各位大大。。。。~
...全文
175 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
tojht 2009-10-28
  • 打赏
  • 举报
回复
谢谢楼上大大的代码 以后又问题还请多多指教。。。 谢谢。。
tojht 2009-10-27
  • 打赏
  • 举报
回复
一共有好几十万的数据 这要跑的什么时候才能算完呀 。。。 都跑了一个半小时了 。。。。。。。。~
tojht 2009-10-27
  • 打赏
  • 举报
回复
其实我也晕 我觉得我写的很罗嗦 应该有很简单的方法 可是我想不出来 所以跑过来请教。。。。。。。。。。。。。
nianran520 2009-10-27
  • 打赏
  • 举报
回复
。。。看晕了,有空做
--小F-- 2009-10-27
  • 打赏
  • 举报
回复
有点晕
jiangshun 2009-10-27
  • 打赏
  • 举报
回复
...
nianran520 2009-10-27
  • 打赏
  • 举报
回复

--测试数据
if object_id('tb') is not null
drop table tb
create table tb(id char(10),yc dec(18,2),ym dec(18,2),type_begin dec(18,2),type_end dec(18,2),month int,code int)

insert into tb
select '101',100.00,120.00,150.00,null,1 ,1 union all
select '101',130.00 ,30.00 ,null,null,2 ,1 union all
select '101',110.00 ,20.00 ,null,null,3 ,1 union all
select '101',170.00 ,70.00 ,null,null,4 ,1 union all
select '101',150.00 ,40.00 ,null,null,5 ,1 union all
select '101',120.00 ,80.00 ,null,null,6 ,1 union all
select '501',1 ,2,5,null,1,1 union all
select '501',2,3 ,null,null,2 ,1 union all
select '501',5,8 ,null,null,3 ,1 union all
select '501',10,12 ,null,null,4 ,1 union all
select '501',32,13 ,null,null,5 ,1 union all
select '501',22,3 ,null,null,6 ,1 union all
select '20201',5 ,7,12,null,1 ,9999 union all
select '20201',13,12,null,null,2,9999 union all
select '20201',23,18,null,null,3,9999 union all
select '20201',15,18,null,null,4,9999 union all
select '20201',10,19,null,null,5,9999 union all
select '20201',16,17,null,null,6,9999 union all
select '20201',16,17,12,null,1,1100 union all
select '20201',13,12,null,null,2,1100 union all
select '20201',23,18,null,null,3,1100 union all
select '20201',15,18,null,null,4,1100 union all
select '20201',10,19,null,null,5,1100 union all
select '20201',16,17,null,null,6,1100
declare @i int
set @i = 2
update tb set type_end = case when substring(id,1,1) in ('1','5') then type_begin +YC - YM
else type_begin +YM-YC end
while @i <= 12
begin
update tb set type_begin = case month when 1 then type_begin
else (select type_end from tb where id = t.id and month = @i - 1 and code = t.code) end
from tb t
where month = @i

update tb set type_end = case when substring(id,1,1) in ('1','5') then type_begin +YC - YM
else type_begin +YM-YC end

set @i = @i + 1
end
select * from tb
drop table tb
--结果
--------------------------
101 100.00 120.00 150.00 130.00 1 1
101 130.00 30.00 130.00 230.00 2 1
101 110.00 20.00 230.00 320.00 3 1
101 170.00 70.00 320.00 420.00 4 1
101 150.00 40.00 420.00 530.00 5 1
101 120.00 80.00 530.00 570.00 6 1
501 1.00 2.00 5.00 4.00 1 1
501 2.00 3.00 4.00 3.00 2 1
501 5.00 8.00 3.00 .00 3 1
501 10.00 12.00 .00 -2.00 4 1
501 32.00 13.00 -2.00 17.00 5 1
501 22.00 3.00 17.00 36.00 6 1
20201 5.00 7.00 12.00 14.00 1 9999
20201 13.00 12.00 14.00 13.00 2 9999
20201 23.00 18.00 13.00 8.00 3 9999
20201 15.00 18.00 8.00 11.00 4 9999
20201 10.00 19.00 11.00 20.00 5 9999
20201 16.00 17.00 20.00 21.00 6 9999
20201 16.00 17.00 12.00 13.00 1 1100
20201 13.00 12.00 13.00 12.00 2 1100
20201 23.00 18.00 12.00 7.00 3 1100
20201 15.00 18.00 7.00 10.00 4 1100
20201 10.00 19.00 10.00 19.00 5 1100
20201 16.00 17.00 19.00 20.00 6 1100
tojht 2009-10-27
  • 打赏
  • 举报
回复
谢谢nianren520的代码 可是 代码有个问题就是 20201 CODE=9999和CODE=1100不是同一个单位的数据 不过是名称相同罢了code=9999的20201 同样自己的12个月的数据 而CODE=1100的 也有自己的12个月的数据
luoyoumou 2009-10-27
  • 打赏
  • 举报
回复
----SQL语句就可以写出来,不用游标的! 
nianran520 2009-10-27
  • 打赏
  • 举报
回复

--测试数据
if object_id('tb') is not null
drop table tb
create table tb(id char(10),yc dec(18,2),ym dec(18,2),type_begin dec(18,2),type_end dec(18,2),month int,code int)

insert into tb
select '101',100.00,120.00,150.00,null,1 ,1 union all
select '101',130.00 ,30.00 ,null,null,2 ,1 union all
select '101',110.00 ,20.00 ,null,null,3 ,1 union all
select '101',170.00 ,70.00 ,null,null,4 ,1 union all
select '101',150.00 ,40.00 ,null,null,5 ,1 union all
select '101',120.00 ,80.00 ,null,null,6 ,1 union all
select '501',1 ,2,5,null,1,1 union all
select '501',2,3 ,null,null,2 ,1 union all
select '501',5,8 ,null,null,3 ,1 union all
select '501',10,12 ,null,null,4 ,1 union all
select '501',32,13 ,null,null,5 ,1 union all
select '501',22,3 ,null,null,6 ,1 union all
select '20201',5 ,7,12,null,1 ,9999 union all
select '20201',13,12,null,null,2,1100 union all
select '20201',23,18,null,null,3,1100 union all
select '20201',15,18,null,null,4,1100 union all
select '20201',10,19,null,null,5,1100 union all
select '20201',16,17,null,null,6,1100
--过程
declare @i int
set @i = 2
update tb set type_end = case when substring(id,1,1) in ('1','5') then type_begin +YC - YM
else type_begin +YM-YC end
while @i <= 12
begin
update tb set type_begin = case month when 1 then type_begin
else (select type_end from tb where id = t.id and month = @i - 1) end
from tb t
where month = @i

update tb set type_end = case when substring(id,1,1) in ('1','5') then type_begin +YC - YM
else type_begin +YM-YC end

set @i = @i + 1
end
select * from tb
drop table tb
--结果
--------------------------
101 100.00 120.00 150.00 130.00 1 1
101 130.00 30.00 130.00 230.00 2 1
101 110.00 20.00 230.00 320.00 3 1
101 170.00 70.00 320.00 420.00 4 1
101 150.00 40.00 420.00 530.00 5 1
101 120.00 80.00 530.00 570.00 6 1
501 1.00 2.00 5.00 4.00 1 1
501 2.00 3.00 4.00 3.00 2 1
501 5.00 8.00 3.00 .00 3 1
501 10.00 12.00 .00 -2.00 4 1
501 32.00 13.00 -2.00 17.00 5 1
501 22.00 3.00 17.00 36.00 6 1
20201 5.00 7.00 12.00 14.00 1 9999
20201 13.00 12.00 14.00 13.00 2 1100
20201 23.00 18.00 13.00 8.00 3 1100
20201 15.00 18.00 8.00 11.00 4 1100
20201 10.00 19.00 11.00 20.00 5 1100
20201 16.00 17.00 20.00 21.00 6 1100

22,297

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧