求日均销量的算法 本日均销量=昨日均销量*0.7+本日合计销量*0.3

tds007 2010-08-15 09:48:08
本日均销量=昨日均销量*0.7+本日合计销量*0.3,应该如何实现这个日均销量算法啊?
假设今天是3号,某商品在1,2,3号这三天的销量分别为5,8,10。
则该商品本日的日均销量为:( 5 * 0.7 +(8 * 0.3)) * 0.7 + 10 * 0.3 = 7.13
...全文
761 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
xman_78tom 2010-08-15
  • 打赏
  • 举报
回复

if OBJECT_ID('tb') is not null
drop table tb;
go
create table tb(dt datetime,sales numeric(10,2));
go
insert into tb
select '2010-08-01',5 union all
select '2010-08-02',8 union all
select '2010-08-03',10;
go

-- 方法 1:递归函数
-- 缺点:受递归层级影响,只能计算 32 天内的日均销量
if OBJECT_ID('ufn_avg_rec') is not null
drop function dbo.ufn_avg_rec;
go
create function dbo.ufn_avg_rec (@date datetime)
returns numeric(10,2) as
begin
declare @avg numeric(10,2);

if @date=(select MIN(dt) from tb)
select @avg=sales from tb where dt=@date;
else
select @avg=dbo.ufn_avg_rec(@date-1)*0.7+sales*0.3 from tb where dt=@date;

return @avg;
end
go

-- 方法 2:游标循环
-- 可以计算超过 32 天的日均销量
if OBJECT_ID('ufn_avg_loop') is not null
drop function dbo.ufn_avg_loop;
go
create function dbo.ufn_avg_loop (@date datetime)
returns numeric(10,2) as
begin
declare @avg numeric(10,2),@sales numeric(10,2);

declare c cursor local for
select sales from tb where dt<=@date order by dt;
open c;
fetch next from c into @avg;
while 1=1
begin
fetch next from c into @sales;
if @@FETCH_STATUS<>0 break;
set @avg=@avg*0.7+@sales*0.3;
end
close c;

return @avg;
end
go

select dbo.ufn_avg_loop('2010-08-03'),dbo.ufn_avg_rec('2010-08-03');
tds007 2010-08-15
  • 打赏
  • 举报
回复
问题解决了,谢谢xman_78tom ,xys_777,谢谢各位的支持和帮助,不胜感激,结帖了。
tds007 2010-08-15
  • 打赏
  • 举报
回复
嗯,可能是我说得还不够详细,还想问得再详细些。
有一个商品销售明细表sale_detail表,记录的是每一笔销售记录的商品明细。
sale_date ,sale_bill_no,sale_item_id,sale_pro_id,sale_qty,sale_price
20100801 010001 1 0000560 5 10.6
20100801 010001 2 0007820 10 30.2
20100801 010002 1 0000560 8 10.6
20100801 010002 2 0023010 5 9.8
每个商品(sale_pro_id)在同一天可能有销售多次,也有可能是好几天都没有过销售记录。
如果这样的情况,具体又应该是如何实现呢?本人不才,还请多指教。


永生天地 2010-08-15
  • 打赏
  • 举报
回复
按楼主需要算法应该这样那个
--sql 2000 函数递归算法2
if object_id('f_test') is not null drop function f_test
go
create function f_test(@dt int)
returns numeric(10,4)
as
begin
declare @i numeric(10,4)
select @i=number+isnull(dbo.f_test(number),0)*0.7 from master..spt_values where type='p' and number=@dt-1
return @i
end
go
select number+dbo.f_test(number)*0.7 from master..spt_values where type='p' and number=3

---select (2+0.7)*0.7+3
/*
---------------------------------------
4.89000

(1 行受影响)

*/
永生天地 2010-08-15
  • 打赏
  • 举报
回复
上面是个例子,用了master数据库里的一个spt_values表的数据
永生天地 2010-08-15
  • 打赏
  • 举报
回复
--sql 2000 函数递归算法
if object_id('f_test') is not null drop function f_test
go
create function f_test(@dt int)
returns int
as
begin
declare @i int
select @i=@dt+isnull(dbo.f_test(number),0) from master..spt_values where type='p' and number=@dt-1
return @i
end
go
select dbo.f_test(10)

/*

-----------
55

(1 行受影响)

*/
tds007 2010-08-15
  • 打赏
  • 举报
回复
是SQL2000,这个函数应该怎么写啊?
永生天地 2010-08-15
  • 打赏
  • 举报
回复
这是一个递归算法,如果sql2005可以用with来实现
如果是sql2000就要从函数上下手,试试
华夏小卒 2010-08-15
  • 打赏
  • 举报
回复


declare @date datetime

select sum(case when datediff(day,sale_date,@date)=2 then sale_qty else 0 end)* 0.49
+sum(case when datediff(day,sale_date,@date)=1 then sale_qty else 0 end)* 0.21
+sum(case when datediff(day,sale_date,@date)=0 then sale_qty else 0 end)* 0.3
from tb


还没测试,不知行不行
华夏小卒 2010-08-15
  • 打赏
  • 举报
回复
感觉可以把:( 5 * 0.7 +(8 * 0.3)) * 0.7 + 10 * 0.3 = 7.13这个公式转化下

如下::5 * 0.7 *0.7 + 8 * 0.3 * 0.7 + 10 * 0.3 = 7.13
即:前天的销量*0.49 + 昨天的销量*0.21 + 今天的销量*0.3


如果对于昨天,或前天没有数据,不用再向前推算销量的情况,将是非常简单的一个问题
Q315054403 2010-08-15
  • 打赏
  • 举报
回复
直接加一个子查询就OK了,搞什么函数、递归呢

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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