有表A,数据如下:
id accno date rn data1 data2 data3
111111111111111111 aaaaaa 2010-4-26 1 500 800
111111111111111111 bbbbbb 2010-5-7 2 1000 800
222222222222222222 dddddd 2010-1-14 1 1000 600
222222222222222222 gggggg 2010-2-7 2 2000 600
222222222222222222 hhhhhh 2010-2-24 3 3000 600
333333333333333333 nnnnnn 2010-3-14 1 500 3000
333333333333333333 mmmmmm 2010-4-11 2 1000 3000
333333333333333333 kkkkkk 2010-1-4 3 2000 3000
333333333333333333 tttttt 2010-5-14 4 4000 3000
333333333333333333 ffffff 2010-5-24 5 8000 3000
字段解释:
同一id下可以有多个accno
rn字段为对相同id按字段date时间排序
data1为日期对应金额
date2为该ID对应的可分摊金额
date3为每个accno实际得到的分摊金额要求在对金额进行分摊时需要注意如下原则:
1、按时间顺序先后来分摊,即优先从日期小的开始分摊
2、每个accno对应的分摊金额不能大于data1
3、每个id对应的分摊金额汇总应该等于该ID对应的dat2
用sql语句分摊完金额,更新至data3字段,则结果应该为 id accno date rn data1 data2 data3
111111111111111111 aaaaaa 2010-4-26 1 500 800 500
111111111111111111 bbbbbb 2010-5-7 2 1000 800 300
222222222222222222 dddddd 2010-1-14 1 1000 600 600
222222222222222222 gggggg 2010-2-7 2 2000 600 0
222222222222222222 hhhhhh 2010-2-24 3 3000 600 0
333333333333333333 nnnnnn 2010-3-14 1 500 3000 500
333333333333333333 mmmmmm 2010-4-11 2 1000 3000 1000
333333333333333333 kkkkkk 2010-1-4 3 2000 3000 1500
333333333333333333 tttttt 2010-5-14 4 4000 3000 0
333333333333333333 ffffff 2010-5-24 5 8000 3000 0请问我的sql语句应该怎么写!!!!!请大虾指教!!!!
id accno date rn data1 data2 data3
111111111111111111 aaaaaa 2010-4-26 1 500 800
111111111111111111 bbbbbb 2010-5-7 2 1000 800
222222222222222222 dddddd 2010-1-14 1 1000 600
222222222222222222 gggggg 2010-2-7 2 2000 600
222222222222222222 hhhhhh 2010-2-24 3 3000 600
333333333333333333 nnnnnn 2010-3-14 1 500 3000
333333333333333333 mmmmmm 2010-4-11 2 1000 3000
333333333333333333 kkkkkk 2010-1-4 3 2000 3000
333333333333333333 tttttt 2010-5-14 4 4000 3000
333333333333333333 ffffff 2010-5-24 5 8000 3000
字段解释:
同一id下可以有多个accno
rn字段为对相同id按字段date时间排序
data1为日期对应金额
date2为该ID对应的可分摊金额
date3为每个accno实际得到的分摊金额要求在对金额进行分摊时需要注意如下原则:
1、按时间顺序先后来分摊,即优先从日期小的开始分摊
2、每个accno对应的分摊金额不能大于data1
3、每个id对应的分摊金额汇总应该等于该ID对应的dat2
用sql语句分摊完金额,更新至data3字段,则结果应该为 id accno date rn data1 data2 data3
111111111111111111 aaaaaa 2010-4-26 1 500 800 500
111111111111111111 bbbbbb 2010-5-7 2 1000 800 300
222222222222222222 dddddd 2010-1-14 1 1000 600 600
222222222222222222 gggggg 2010-2-7 2 2000 600 0
222222222222222222 hhhhhh 2010-2-24 3 3000 600 0
333333333333333333 nnnnnn 2010-3-14 1 500 3000 500
333333333333333333 mmmmmm 2010-4-11 2 1000 3000 1000
333333333333333333 kkkkkk 2010-1-4 3 2000 3000 1500
333333333333333333 tttttt 2010-5-14 4 4000 3000 0
333333333333333333 ffffff 2010-5-24 5 8000 3000 0请问我的sql语句应该怎么写!!!!!请大虾指教!!!!
不过,看数据好象明白了。
不过,真得挺复杂。
还是写存储过程来实现比较合适,在存储过程里用Cursor循环取出每个ID对应的记录。针对每条记录做计算。
declare
v_totall_m number; ----可分配金额
begin
for c1 in (select distinct id from t) loop
select data1 from t into v_totall_m;
for v_c in (select accno,data2 from t where t.id = c1.id order by date asc) loop
if v_totall_m - v_c.data2 > 0 then
update t set data3 = v_c.data2 where accno = v_c.accno and id = c1.id;
v_totall_m:= v_totall_m - v_c.data2;
else
update t set data3 = v_totall_m where accno = v_c.accno and id = c1.id;
goto l1;
end if;
end loop;
<<l1>>
commit;
end loop;
end;为了赚点技术分不容易啊,哎
v_totall_m number; ----可分配金额
begin
for c1 in (select distinct id from t) loop
select data2 from t into v_totall_m;
for v_c in (select accno,data1 from t where t.id = c1.id order by date asc) loop
if v_totall_m - v_c.data1 > 0 then
update t set data3 = v_c.data1 where accno = v_c.accno and id = c1.id;
v_totall_m:= v_totall_m - v_c.data1;
else
update t set data3 = v_totall_m where accno = v_c.accno and id = c1.id;
goto l1;
end if;
end loop;
<<l1>>
commit;
end loop;
end;上面好像列名写反了
不行啊,报错了。黄岛主救命啊。
第5行 select data1 from t into v_totall_m; 的into报错:命令未正确结束。
哎,仔细一看错误还真不少
v_totall_m number; ----可分配金额
begin
for c1 in (select distinct id from t) loop
select data1 into v_totall_m from t where t.id = c1.id and rownum <2;
for v_c in (select accno,data1 from t where t.id = c1.id order by date asc) loop
if v_totall_m - v_c.data1 > 0 then
update t set data3 = v_c.data1 where accno = v_c.accno and id = c1.id;
v_totall_m:= v_totall_m - v_c.data1;
else
update t set data3 = v_totall_m where accno = v_c.accno and id = c1.id;
goto l1;
end if;
end loop;
<<l1>>
commit;
end loop;
end;还是发个完整的吧
恩,应该是select data2 into v_totall_m from t where t.id = c1.id and rownum <2;
执行没报错了。我套到我的SQL里执行试试。非常感谢
n_money number; --可分配金额
s_accno char(6);
n_data1 number;
n_data2 number;
n_data3 number;
cursor c2(n_id number) is select accno,data1,data2 from a where id=n_id order by date;
begin
for c1 in (select distinct id from a) loop
n_money:=0;
n_data3:=0;
open c2;
loop
fetch c2 into s_accno,nvl(n_data1,0),nvl(n_data2,0);
exit when c2%notfound;
if c2%rowcount=1 then
n_money:=n_data2-n_data1;
if n_money<0 then
n_data3:=n_data2;
else
n_data3:=n_data2-n_data1;
end if;
else
if n_money< 0 then
n_data3:=0;
else
if n_money<n_data1 then
n_data3:=n_money;
else
n_data3:=n_money-n_data1
end if;
end if ;
end if ;
update a set data3 = n_data3 where accno = s_accno and id = c1.id;
end loop;
close c2;
end loop;
commit;
end;
但是goto l1 是什么意思,以前没用过goto。最后<<l1>> commit;这个<<l1>> 是起什么作用呢。
GOTO的作用是跳出第一个FOR循环 ,
没用过GOTO,可以到网上搜一下GOTO的用法,这个用法一般不建议使用,
会破坏程序结构的完整性.
v_totall_m number; ----可分配金额
begin
for c1 in (select distinct id from t) loop
select data1 from t into v_totall_m;
for v_c in (select accno,data2 from t where t.id = c1.id order by date asc) loop
if v_totall_m - v_c.data2 > 0 then
update t set data3 = v_c.data2 where accno = v_c.accno and id = c1.id;
v_totall_m:= v_totall_m - v_c.data2;
else
update t set data3 = v_totall_m where accno = v_c.accno and id = c1.id;
goto l1;
end if;
end loop;
<<l1>>
commit;
end loop;
end;