全月加权平均的计算(分仓核算,结果反填到单据)

http://topic.csdn.net/u/20090918/20/ba975da3-dc93-47a5-8456-d5d7f1146705.html?73024

环境:MSSQL2000 高难度全月加权平均
表IO_STORE ----出入库明细 ISIND=1为进仓单 ; ISIND=0为出仓单
采用全月一次加权平均法计算单价,本月结存单价、数量、金额作为下月的期初,如此类推;
根据不同的查询起始日期和结束日期有不同的结果
注意:如果是调拨单的调入单价则必须取调出单价
仓库 单号 日期 货品 数量 单价 金额 进/出仓
STORE BC BD GOODS QTY PRICE AM ISIN
原料仓 IN001 2009-07-30 A001 300 20 6000 1 --7月份
原料仓 IN002 2009-07-29 B001 400 2 800 1
原料仓 IN101 2009-08-01 A001 30 20 600 1 --8月份
原料仓 IN103 2009-08-20 A001 50 22 1100 1
原料仓 IN203 2009-08-25 A001 20 23 460 1
原料仓 IN123 2009-08-26 B001 300 2 600 1

原料仓 OU100 2009-08-26 A001 30 0 0 0 --8月份出仓
原料仓 OU202 2009-08-27 B001 20 0 0 0
原料仓 OU132 2009-08-29 B001 40 0 0 0

原料仓 IN123 2009-09-01 A001 500 21 10500 1 ---9月份进仓
原料仓 IN125 2009-09-20 B001 500 2.2 1100 1
半成仓 OU129 2009-09-25 B001 23 0 0 1 ---此为调拨单 单号相同 这里没有单价

原料仓 OU211 2009-09-08 A001 100 0 0 0 ---9月份出仓
原料仓 OU213 2009-09-27 B001 120 0 0 0
原料仓 OU129 2009-09-25 B001 23 0 0 0 ---此为调拨单 单号相同


求结果如下有2点:
1/第一种方案 (希望能做成函数)
(@FROMDATE DATETIME, @TODATE DATETIME) ---查询 ('2009-08-01','2009-08-31')
仓库 货品 期初数量 期初单价 期初金额 收入数量 收入单价 收入金额 发出数量 发出单价 发出金额 结存数量 结存单价 结存金额
STORE GOODS SQT SPRICE SAM IQT IPRICE IAM OQT OPRICE OAM EQT EPRICE EAM
原料仓 A001 300 20 6,000.00 100 21.6 2,160.00 70 20.4 1,428.00 330 20.4 6,732.00
原料仓 B001 400 2 800 300 2 600 20 2 40 680 2 1,360.00

(@FROMDATE DATETIME, @TODATE DATETIME) ---查询 ('2009-09-01','2009-08-30')
仓库 货品 期初数量 期初单价 期初金额 收入数量 收入单价 收入金额 发出数量 发出单价 发出金额 结存数量 结存单价 结存金额
STORE GOODS SQT SPRICE SAM IQT IPRICE IAM OQT OPRICE OAM EQT EPRICE EAM
原料仓 A001 330 20.4 6,732.00 500 21 10,500.00 100 20.761 2,076.14 730 20.761 15,155.86
原料仓 B001 680 2 1,360.00 500 2.2 1,100.00 143 2.085 298.12 1,037 2.085 2,161.88

半成仓 B001 0 0 0 23 2.085 47.95 0 0 0 23 2.085 47.95

2/求把计算出来的当天的发出单价回填到出仓单和进仓单(调拨单) ISIND=0为出仓单
还有补充说明一下, 在调拨单中 出仓单和进仓单 单号是一样的。

/*---------------------------------
-- Author : htl258(Tony)
-- Date : 2009-09-19 01:17:51
-- Version: Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86)
Mar 29 2009 10:27:29
Copyright (c) 1988-2008 Microsoft Corporation
Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 2)

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

IF NOT OBJECT_ID('[tb]') IS NULL
DROP TABLE [tb]
GO
CREATE TABLE [tb]([STORE] NVARCHAR(10),[BC] NVARCHAR(10),[BD] DATETIME,[GOODS] NVARCHAR(10),[QTY] INT,[PRICE] DECIMAL(18,1),[AM] INT,[ISIN] INT)
INSERT [tb]
SELECT N'原料仓','IN001',N'2009-07-30','A001',300,20,6000,1 UNION ALL
SELECT N'原料仓','IN002',N'2009-07-29','B001',400,2,800,1 UNION ALL
SELECT N'原料仓','IN101',N'2009-08-01','A001',30,20,600,1 UNION ALL
SELECT N'原料仓','IN103',N'2009-08-20','A001',50,22,1100,1 UNION ALL
SELECT N'原料仓','IN203',N'2009-08-25','A001',20,23,460,1 UNION ALL
SELECT N'原料仓','IN123',N'2009-08-26','B001',300,2,600,1 UNION ALL
SELECT N'原料仓','OU100',N'2009-08-26','A001',30,0,0,0 UNION ALL
SELECT N'原料仓','OU202',N'2009-08-27','B001',20,0,0,0 UNION ALL
SELECT N'原料仓','OU132',N'2009-08-29','B001',40,0,0,0 UNION ALL
SELECT N'原料仓','IN123',N'2009-09-01','A001',500,21,10500,1 UNION ALL
SELECT N'原料仓','IN125',N'2009-09-20','B001',500,2.2,1100,1 UNION ALL
SELECT N'半成仓','OU129',N'2009-09-25','B001',23,0,0,1 UNION ALL
SELECT N'原料仓','OU211',N'2009-09-08','A001',100,0,0,0 UNION ALL
SELECT N'原料仓','OU213',N'2009-09-27','B001',120,0,0,0 UNION ALL
SELECT N'原料仓','OU129',N'2009-09-25','B001',23,0,0,0
GO
--SELECT * FROM [tb]

-->SQL查询如下:
--
创建更新单价的存储过程:
IF NOT OBJECT_ID('[sp_up_price]') IS NULL
DROP PROC [sp_up_price]
GO
CREATE PROC sp_up_price
AS
SET NOCOUNT ON
DECLARE @m VARCHAR(7)
DECLARE c CURSOR FOR
SELECT CONVERT(VARCHAR(7),BD,23)
FROM tb
GROUP BY CONVERT(VARCHAR(7),BD,23)
ORDER BY 1
OPEN c
FETCH NEXT FROM c INTO @m
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE a SET
a.price
=b.price,a.am=b.price*a.qty
FROM TB AS a
JOIN (
SELECT store,goods,CAST(SUM(amt)*1./SUM(qty) AS DECIMAL(18,2)) AS price
FROM (
--获取本月的数量金额
SELECT store,goods,
amt
=SUM(CASE isin WHEN 1 THEN am ELSE 0 END),
qty
=SUM(CASE isin WHEN 1 THEN qty ELSE 0 END)
FROM tb
WHERE BD BETWEEN CAST(@m+'-01' AS DATETIME) AND DATEADD(ms,-3,DATEADD(mm,1,@m+'-01'))
GROUP BY store,goods
UNION ALL
--获取本月期初的数量金额
SELECT store,goods,
amt
=SUM(CASE isin WHEN 1 THEN am ELSE -am END),--金额
qty=SUM(CASE isin WHEN 1 THEN qty ELSE -qty END) --数量
FROM tb
WHERE BD < CAST(@m+'-01' AS DATETIME)
GROUP BY store,goods
)
AS t
GROUP BY store,goods
)
AS B
ON a.store=b.store AND a.goods=b.goods
WHERE a.BD BETWEEN CAST(@m+'-01' AS DATETIME) AND DATEADD(ms,-3,DATEADD(mm,1,@m+'-01'))
AND a.isin=0
--更新调拨单单价
UPDATE a SET
a.price
=b.price,a.am=a.qty*b.price
FROM (
SELECT * FROM TB
WHERE isin=1 AND price=0
AND BD BETWEEN CAST(@m+'-01' AS DATETIME)
AND DATEADD(ms,-3,DATEADD(mm,1,@m+'-01'))
)
AS a
JOIN (
SELECT * FROM TB
WHERE isin=0
AND BD BETWEEN CAST(@m+'-01' AS DATETIME)
AND DATEADD(ms,-3,DATEADD(mm,1,@m+'-01'))
)
AS b
ON a.goods=b.goods AND a.bc=b.bc--加个这个条件

FETCH NEXT FROM c INTO @m
END
CLOSE c
DEALLOCATE c
SET NOCOUNT OFF
GO

--执行更新反填单价:
EXEC sp_up_price
--查询结果:
SELECT * FROM tb
/*
STORE BC BD GOODS QTY PRICE AM ISIN
---------- ---------- ----------------------- ---------- ----------- --------------------------------------- ----------- -----------
原料仓 IN001 2009-07-30 00:00:00.000 A001 300 20.0 6000 1
原料仓 IN002 2009-07-29 00:00:00.000 B001 400 2.0 800 1
原料仓 IN101 2009-08-01 00:00:00.000 A001 30 20.0 600 1
原料仓 IN103 2009-08-20 00:00:00.000 A001 50 22.0 1100 1
原料仓 IN203 2009-08-25 00:00:00.000 A001 20 23.0 460 1
原料仓 IN123 2009-08-26 00:00:00.000 B001 300 2.0 600 1
原料仓 OU100 2009-08-26 00:00:00.000 A001 30 20.4 612 0
原料仓 OU202 2009-08-27 00:00:00.000 B001 20 2.0 40 0
原料仓 OU132 2009-08-29 00:00:00.000 B001 40 2.0 80 0
原料仓 IN123 2009-09-01 00:00:00.000 A001 500 21.0 10500 1
原料仓 IN125 2009-09-20 00:00:00.000 B001 500 2.2 1100 1
半成仓 OU129 2009-09-25 00:00:00.000 B001 23 2.1 48 1
原料仓 OU211 2009-09-08 00:00:00.000 A001 100 20.7 2074 0
原料仓 OU213 2009-09-27 00:00:00.000 B001 120 2.1 250 0
原料仓 OU129 2009-09-25 00:00:00.000 B001 23 2.1 48 0

(15 行受影响)
*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值