昨天有人让我帮忙写个算移动加权平均的SQL语句,我想了半天终于写出来正确的了。现在发出来供大家参考、讨论。

if OBJECT_ID('tb') is not null drop table tb
if OBJECT_ID('TEMP') is not null drop table TEMP
if OBJECT_ID('FUN_NOWPRICE') is not null drop FUNCTION FUN_NOWPRICE
if OBJECT_ID('FUN_NOWQTY') is not null drop FUNCTION FUN_NOWQTY
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)   
--也就是说进货的时候单价更新为(当前库存的总价值+库总价值)/入库后总数量

以此类推...
*/

--想了半天,觉得只能用循环、递归、游标实现,因为出库时的价格是根据之前的记录算出来的。
--也许有经典的算法,谁知道的麻烦教教我或者发个链接。

--这个FUNCTION就是变相实现递归的
CREATE FUNCTION FUN_NOWPRICE(@ID INT)
RETURNS NUMERIC(19,6)
AS
BEGIN
RETURN (SELECT ISNULL(NOWPRICE,0) FROM
(SELECT MAX(NOWPRICE) 'NOWPRICE' FROM TEMP T1 WHERE ID<@ID AND
NOT EXISTS(SELECT 1 FROM TEMP WHERE ID>T1.ID AND ID<@ID))
T)
END
GO
--这个FUNCTION是为了计算方便
CREATE FUNCTION FUN_NOWQTY(@ID INT)
RETURNS NUMERIC(19,6)
AS
BEGIN
RETURN (SELECT ISNULL(SUM(CASE CTYPE WHEN '进货' THEN QNT ELSE 0-QNT END),0) FROM TEMP WHERE ID<@ID)
END
GO

--建一个临时表,包含原表参与运算的全部字段
create table TEMP(
id INT
,Date1 datetime
,ctype varchar(10)
,qnt float
,pri float
,NOWPRICE AS
CASE ctype
WHEN '出货' THEN DBO.FUN_NOWPRICE(ID)
ELSE (DBO.FUN_NOWPRICE(ID)*DBO.FUN_NOWQTY(ID)+QNT*PRI)/(DBO.FUN_NOWQTY(ID)+QNT)
END)

INSERT INTO TEMP
SELECT * FROM TB
ORDER BY DATE1 ASC,ID ASC

SELECT * FROM TEMP

/*
0    2009-01-01 00:00:00.000    进货    10    100    100
1    2009-01-01 00:00:00.000    进货    50    120    116.666666666667
2    2009-01-02 00:00:00.000    出货    30    150    116.666667
3    2009-01-03 00:00:00.000    进货    40    130    124.285714428571
4    2009-01-03 00:00:00.000    出货    25    160    124.285714
*/

这个写法的不完善处在于它是根据ID和日期对记录进行排序的,对于同一天的出入库情况没有处理。实际运用中可以根据CREATEDATE等时间标志性字段来进行排序。


第一次写技术性博客,希望这是一个好的开始,欢迎大家对我的算法进行指正^_^

用计算列实现移动加权平均算法相关推荐

  1. Power BI:M与DAX以及度量与计算列

    When I embarked on my Power BI journey I was almost immediately slapped with an onslaught of foreign ...

  2. 【MSWA交通流量分配】基于相继加权平均算法(MSWA)交通流量分配算法的仿真

    1.软件版本 matlab2021a 2.本算法理论知识 如图所示交通网络中,包含6个节点.11各路段.9个OD对.经枚举可得每个OD对间存在3条无折返有效路径,共27条. 各个OD对间的出行需求量如 ...

  3. 基于向量加权平均算法的函数寻优和工程优化

    文章目录 一.理论基础 1.向量加权平均算法 (1)更新规则阶段 (2)向量合并阶段 (3)局部搜索阶段 2.INFO算法伪代码 二.仿真实验与分析 1.函数优化 2.工程优化 三.参考文献 一.理论 ...

  4. 非正常情况下的移动加权平均算法

    非正常情况下的移动加权平均算法 什么叫移动加权平均法? 百度上的解释:移动加权平均法是指以每次进货的成本加上原有库存存货的成本,除以每次进货数量与原有库存存货的数量之和, 据以计算加权平均单位成本,以 ...

  5. 在DataTable中创建计算列

    我们知道DataTable是内存中的一个表,可以用DataColumn和DataRow来构造一个DataTable,并且用DataColumn的Expression属性来创建计算列. (1)创建计算列 ...

  6. MySQL 5.7中的更多改进,包括计算列

    让我们继续上一周的内容,讨论MySQL 5.7中的新特性,我们将把注意力集中于新的安全方面的特性.首先,新版本中取消了mysql_old_password这个认证插件.其实这个插件从版本4.x开始就已 ...

  7. SharePoint 2007 如果在计算列中使用Today变量

    默认情况下在SharePoint计算列的公式中是没办法使用Today这个变量的.如果使用,在保存的时候我们会得到这个错误信息. Calculated columns cannot contain vo ...

  8. C++ number of positive divisors计算正除数的实现算法(附完整源码)

    C++number of positive divisors计算正除数的实现算法 C++number of positive divisors计算正除数的实现算法完整源码(定义,实现,main函数测试 ...

  9. oauth_client_details的值怎么添加_PowerBI计算列与度量值

    有两个地方可以输入DAX公式:计算列和度量值. 1 新建列 Power BI虽然源于Excel,但毕竟是不同的产品.我们要试图抛弃Excel中单元格思维的方式,在BI中的表是以列式存储,没有Excel ...

最新文章

  1. sql常用语句使用方法
  2. P2119 魔法阵(优化枚举,数学运算优化)难度⭐⭐⭐★
  3. vm虚拟机linux磁盘空间不足,手动扩大
  4. 使用ASP.NET MVC 2编程时遇到的两个小问题
  5. pycharm运行出现ImportError:No module named
  6. mysql 报错注入 读文件_SQL注入-读写文件
  7. 调用接口处理时间过长,前端访问超时解决方案
  8. shell 需要注意的点
  9. 哈哈哈哈哈!“科研打工人”的凡尔赛
  10. 鸟哥基础-读书笔记一
  11. jQuery 引用地址{包括jquery和google提供的地址}, 节省你不必要的流量
  12. Linux用户和用户组和文件权限介绍
  13. eclipse设置黑色主题
  14. 哪个说了算?漫谈网吧网络的稳定和安全(转)
  15. 仿iReader 阅读器(swift)
  16. 包工协议书样本_个人承包协议书范本
  17. MySQL全文索引及其优劣
  18. JPG格式图片怎么减小体积?一招教你轻松压缩JPG图片
  19. visual studio 总是和搜狗输入法冲突
  20. java实现正态分布累积分布_标准正态分布变量的累积概率分布函数

热门文章

  1. JZOJ3815. 【NOIP2014模拟9.7】克卜勒
  2. 【Lifelong learning】Achieving Forgetting Prevention and Knowledge Transfer in Continual Learning
  3. 基于阈值方法的大津法(OTSU算法)---图像分割
  4. 计算机学科课程知识体系回顾初步
  5. 蓝牙定位技术使室内定位更加精准--高精度定位--新导智能
  6. 【一起入门MachineLearning】中科院机器学习-期末题库-【单选题54,47,51,55,64+简答题8,10,23】
  7. git设置记住用户名和密码,不用每次都输入
  8. 习题42 对象、类及从属关系
  9. 小葫芦直播管家找不到服务器,小葫芦直播管家显示启动模块失败怎么办?
  10. 360浏览器自动刷新选项设置方法