您的位置:首页 > 其它

移动加权平均算法应用实例

2010-04-17 18:16 267 查看
/*------------------------------------------------------------------
-- Author : htl258(Tony)
-- Date : 2010-04-17 14:10:13
-- Version: Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
Jul 9 2008 14:43:34
Copyright (c) 1988-2008 Microsoft Corporation
Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

------------------------------------------------------------------*/
--> 生成测试数据表:tb

IF OBJECT_ID('[tb]') IS NOT NULL
DROP TABLE [tb]
GO
create table tb(
id INT
,Date1 datetime
,ctype varchar(10)
,qnt float
,pri float
)

--qnt 数量
--pri 单价
insert tb
select 0,'2009-1-1', '进货', 10, 100 union all
select 1,'2009-1-1', '进货', 50, 120 union all
select 2,'2009-1-2', '出货', 30, 150 union all
select 3,'2009-1-3', '进货', 40, 130 union all
select 4,'2009-1-3', '出货', 25, 160
GO
-- 我要算成本价,按移动加权平均

/*
1进货以后的成本价c1=(10*100+50*120)/(10+50)
2出货以后的成本价c2=((10+50)*c1-30*c1)/((10+50)-30)=C2
--也就是说出货的时候价格不变
3进货以后的成本价c3=(((10+50)-30)*c2+40*130)/((10+50)-30+40)
--也就是说进货的时候单价更新为(当前库存的总价值+库总价值)/入库后总数量


以此类推...
*/
--happyflystone:
alter table tb add newc int;
alter table tb add nowpric numeric(18,12)
go

update b set
newc =isnull((select sum( case when ctype= '进货' then qnt else -qnt end)
from tb
where id <=b.id),0)
from tb b

declare @d numeric(18,12)
set @d = 0

update tb set
nowpric = @d*1.0/newc,
@d = @d + case when ctype = '进货' then qnt else - qnt end *
case when ctype = '进货' then pri else @d*1.0 / (newc+qnt) end

select * from tb
/*
id Date1 ctype qnt pri newc nowpric
0 2009-01-01 00:00:00.000 进货 10 100 10 100.000000000000
1 2009-01-01 00:00:00.000 进货 50 120 60 116.666666666667
2 2009-01-02 00:00:00.000 出货 30 150 30 116.666666666667
3 2009-01-03 00:00:00.000 进货 40 130 70 124.285714285714
4 2009-01-03 00:00:00.000 出货 25 160 45 124.285714285714
*/







表TEST
id(主键) 字段1 字段2 字段3
1 5.00 2 0.00
3 6.00 5 0.00
4 10.00 3 0.00
5 8.00 2 0.00
6 16.00 4 0.00
...
如何移动加权平均得到字段3
id(主键) 字段1 字段2 字段3
1 5.00 2 5.00
3 6.00 5 5.00
4 10.00 3 57.14=(5.00*2+6.00*5)/(2+5)
5 8.00 2 7.00=(5.00*2+6.00*5+10.00*3)/(2+5+3)
6 16.00 4 7.17=(5.00*2+6.00*5+10.00*3+8.00*2)/(2+5+3+2)
---------------------------------------------------------
create table tb(id int ,字段1 numeric(8,2) , 字段2 int , 字段3 numeric(8,2))
insert into tb select 1,5.00,2,0.00
insert into tb select 3,6.00,5,0.00
insert into tb select 4,10.00,3,0.00
insert into tb select 5,8.00,2,0.00
insert into tb select 6,16.00,4,0.00
go

select id , 字段1 , 字段2 , 字段3 = isnull((select sum(字段1*字段2) / sum(字段2) from tb where id < t.id),字段1) from tb t

drop table tb

/*
id 字段1 字段2 字段3
---- ----- ----- ---------
1 5.00 2 5.000000
3 6.00 5 5.000000
4 10.00 3 5.714285
5 8.00 2 7.000000
6 16.00 4 7.166666

(所影响的行数为 5 行)
*/
此例转自:http://topic.csdn.net/u/20080310/13/39629d84-7d44-4de0-a010-2a6688894ab8.html?seed=1944131440
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: