请大家解决个 数据(数量)拆分的问题????
请大家解决个 数据(数量)拆分的问题????
按照数量拆分数据,合并成一个表
表A
物料 数量 日期
A001 100 2005-05-05
A001 120 2005-05-06
A001 135 2005-05-07
B001 100 2005-05-06
表B
物料 数量 日期
A001 80 2005-05-08
A001 145 2005-05-09
B001 10 2005-05-10
C001 10 2005-05-09
结果:
物料 数量 A表日期 B表日期
A001 80 2005-05-05 2005-05-08
A001 20 2005-05-05 2005-05-09
A001 120 2005-05-06 2005-05-09
A001 5 2005-05-07 2005-05-09
A001 130 2005-05-07 2005-05-09
B001 10 2005-05-06 2005-05-10
B001 90 2005-05-06 null
C001 10 null 2005-05-09
[解决办法]
这个很难,吃饭了再看
[解决办法]
没看懂结果是如何来的?
[解决办法]
用游标的方法测试成功
--建立环境
declare @A table (
物料 varchar(20),
数量 int,
日期 datetime
)
insert @a select
'A001 ', 100, '2005-05-05 '
union all select
'A001 ', 120, '2005-05-06 '
union all select
'A001 ', 135, '2005-05-07 '
union all select
'B001 ', 100, '2005-05-06 '
declare @B table(
物料 varchar(20),
数量 int,
日期 datetime
)
insert @b select
'A001 ', 80, '2005-05-08 '
union all select
'A001 ', 145, '2005-05-09 '
union all select
'B001 ', 10, '2005-05-10 '
union all select
'C001 ', 10, '2005-05-09 '
--开始计算
declare @物料a varchar(20)
declare @物料b varchar(20)
declare @数量a int
declare @数量b int
declare @日期a datetime
declare @日期b datetime
declare @FETCH_STATUS_a int
declare @FETCH_STATUS_b int
declare cur_a CURSOR LOCAL READ_ONLY for
select * from @a order by 物料,日期
declare cur_b CURSOR LOCAL READ_ONLY for
select * from @b order by 物料,日期
open cur_a
open cur_b
declare @结果 table (
物料 varchar(20),
数量 int,
A表日期 datetime,
B表日期 datetime
)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
while 1=1
begin
if @FETCH_STATUS_a <> 0
begin
while @FETCH_STATUS_b=0
begin
insert @结果 values(@物料b, @数量b, null, @日期b)
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
goto theEnd
end
if @FETCH_STATUS_b <> 0
begin
while @FETCH_STATUS_a=0
begin
insert @结果 values(@物料a, @数量a, @日期a,null)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
goto theEnd
end
if @物料a <@物料b
begin
insert @结果 values(@物料a, @数量a, @日期a,null)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
elseif @物料a> @物料b
begin
insert @结果 values(@物料b, @数量b,null, @日期b)
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
else
begin
if @数量a <@数量b
begin
insert @结果 values(@物料a, @数量a, @日期a,@日期b)
set @数量b=@数量b-@数量a
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
else if @数量a> @数量b
begin
insert @结果 values(@物料a, @数量b, @日期a,@日期b)
set @数量a=@数量a-@数量b
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
else
begin
insert @结果 values(@物料a, @数量a, @日期a,@日期b)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
end
end
theEnd:
--显示结果
select * from @结果
--删除游标
CLOSE cur_a
DEALLOCATE cur_a
CLOSE cur_b
DEALLOCATE cur_b
--结果
物料 数量 A表日期 B表日期
-------------------- ----------- ------------------------------------------------------ ------------------------------------------------------
A001 80 2005-05-05 00:00:00.000 2005-05-08 00:00:00.000
A001 20 2005-05-05 00:00:00.000 2005-05-09 00:00:00.000
A001 120 2005-05-06 00:00:00.000 2005-05-09 00:00:00.000
A001 5 2005-05-07 00:00:00.000 2005-05-09 00:00:00.000
A001 130 2005-05-07 00:00:00.000 NULL
B001 10 2005-05-06 00:00:00.000 2005-05-10 00:00:00.000
B001 90 2005-05-06 00:00:00.000 NULL
C001 10 NULL 2005-05-09 00:00:00.000
(所影响的行数为 8 行)
ps:楼主做的130的那一行错误了
[解决办法]
--加多条数据测试(测试开始物料不相等的情况),应该没问题了
--建立环境
declare @A table (
物料 varchar(20),
数量 int,
日期 datetime
)
insert @a select
'A000 ', 100, '2005-05-05 '
union all select
'A001 ', 100, '2005-05-05 '
union all select
'A001 ', 120, '2005-05-06 '
union all select
'A001 ', 135, '2005-05-07 '
union all select
'B001 ', 100, '2005-05-06 '
declare @B table(
物料 varchar(20),
数量 int,
日期 datetime
)
insert @b select
'A001 ', 80, '2005-05-08 '
union all select
'A001 ', 145, '2005-05-09 '
union all select
'B001 ', 10, '2005-05-10 '
union all select
'C001 ', 10, '2005-05-09 '
--开始计算
declare @物料a varchar(20)
declare @物料b varchar(20)
declare @数量a int
declare @数量b int
declare @日期a datetime
declare @日期b datetime
declare @FETCH_STATUS_a int
declare @FETCH_STATUS_b int
declare cur_a CURSOR LOCAL READ_ONLY for
select * from @a order by 物料,日期
declare cur_b CURSOR LOCAL READ_ONLY for
select * from @b order by 物料,日期
open cur_a
open cur_b
declare @结果 table (
物料 varchar(20),
数量 int,
A表日期 datetime,
B表日期 datetime
)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
while 1=1
begin
if @FETCH_STATUS_a <> 0
begin
while @FETCH_STATUS_b=0
begin
insert @结果 values(@物料b, @数量b, null, @日期b)
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
goto theEnd
end
if @FETCH_STATUS_b <> 0
begin
while @FETCH_STATUS_a=0
begin
insert @结果 values(@物料a, @数量a, @日期a,null)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
goto theEnd
end
if @物料a <@物料b
begin
insert @结果 values(@物料a, @数量a, @日期a,null)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
elseif @物料a> @物料b
begin
insert @结果 values(@物料b, @数量b,null, @日期b)
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
else
begin
if @数量a <@数量b
begin
insert @结果 values(@物料a, @数量a, @日期a,@日期b)
set @数量b=@数量b-@数量a
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
end
else if @数量a> @数量b
begin
insert @结果 values(@物料a, @数量b, @日期a,@日期b)
set @数量a=@数量a-@数量b
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
else
begin
insert @结果 values(@物料a, @数量a, @日期a,@日期b)
FETCH NEXT FROM cur_a
INTO @物料a, @数量a, @日期a
set @FETCH_STATUS_a=@@FETCH_STATUS
FETCH NEXT FROM cur_b
INTO @物料b, @数量b, @日期b
set @FETCH_STATUS_b=@@FETCH_STATUS
end
end
end
theEnd:
--显示结果
select * from @结果
--删除游标
CLOSE cur_a
DEALLOCATE cur_a
CLOSE cur_b
DEALLOCATE cur_b
--结果
物料 数量 A表日期 B表日期
-------------------- ----------- ------------------------------------------------------ ------------------------------------------------------
A000 100 2005-05-05 00:00:00.000 NULL
A001 80 2005-05-05 00:00:00.000 2005-05-08 00:00:00.000
A001 20 2005-05-05 00:00:00.000 2005-05-09 00:00:00.000
A001 120 2005-05-06 00:00:00.000 2005-05-09 00:00:00.000
A001 5 2005-05-07 00:00:00.000 2005-05-09 00:00:00.000
A001 130 2005-05-07 00:00:00.000 NULL
B001 10 2005-05-06 00:00:00.000 2005-05-10 00:00:00.000
B001 90 2005-05-06 00:00:00.000 NULL
C001 10 NULL 2005-05-09 00:00:00.000
(所影响的行数为 9 行)
[解决办法]
试一下不用游标的先进先出算法:
----创建测试数据
if object_id( 'tempdb..#tmp ') is not null
drop table #tmp
if object_id( 'tempdb..#tmp2 ') is not null
drop table #tmp2
GO
declare @ta table(物料 varchar(10), 数量 int, 日期 varchar(10))
insert @ta
select 'A001 ', 100, '2005-05-05 ' union all
select 'A001 ', 120, '2005-05-06 ' union all
select 'A001 ', 135, '2005-05-07 ' union all
select 'B001 ', 100, '2005-05-06 '
declare @tb table(物料 varchar(10), 数量 int, 日期 varchar(10))
insert @tb
select 'A001 ', 80, '2005-05-08 ' union all
select 'A001 ', 145, '2005-05-09 ' union all
select 'B001 ', 10, '2005-05-10 ' union all
select 'C001 ', 10, '2005-05-09 '
----生成临时表1,用于实现每次出库对应的入库关系(即每次出库都来自哪几个入库)
SELECT a.物料,a.数量 as 出库数量,b.数量 as 入库数量,
a.日期 as 出库日期,b.日期 as 入库日期 ,
库存 = (select sum(数量) from @ta where 物料 = b.物料 and 日期 <= b.日期) -
(select sum(数量) from @tb where 物料 = a.物料 and 日期 <= a.日期)
INTO #tmp FROM @tb AS a LEFT JOIN @ta as b ON a.物料 = b.物料 AND
isnull((select sum(数量) from @tb where 物料 = a.物料 and 日期 <= a.日期),0) > =
isnull((select sum(数量) from @ta where 物料 = b.物料 and 日期 < b.日期),0)
AND
b.日期 > = isnull((select max(y.日期) from @tb as x
inner join @ta as y on x.物料 = y.物料
and x.日期 =(select max(日期) from @tb where 物料 = a.物料 and 日期 < a.日期)
and
isnull((select sum(数量) from @tb where 物料 = x.物料 and 日期 <= x.日期),0) > =
isnull((select sum(数量) from @ta where 物料 = y.物料 and 日期 < y.日期),0)), ' ')
ORDER BY a.物料, a.日期,b.日期
----生成临时表2,用于获得每次出库时之前的库存
SELECT 物料,出库日期,库存 INTO #tmp2 FROM #tmp AS t
WHERE not exists(select 1 from #tmp where 物料 = t.物料 and 出库日期 = t.出库日期 and 入库日期 > t.入库日期)
----出库数量拆分
SELECT a.物料,
数量 =
CASE
--本次出库的第一次出库
WHEN a.入库日期 = (select min(入库日期) from #tmp where 出库日期 = a.出库日期)
--本次出库的第一次出库数量来自于上一次出库结束的库存
THEN case when b.库存 > a.出库数量 then a.出库数量 else isnull(b.库存,a.出库数量) end
ELSE
case
when --当截至某次入库的累计入库仍不够本次出库时,则此次入库全部出库
a.出库数量 - - b.库存 - isnull((select sum(入库数量) from #tmp
where 物料 = a.物料 and 出库日期 = a.出库日期 and 入库日期 <= a.入库日期 and 入库日期 >
(select min(入库日期) from #tmp where 物料 = a.物料 and 出库日期 = a.出库日期)),0)
> = 0
then a.入库数量
else --否则表示截至某次入库时,则累计的入库已满足出库需要,计算从该次入库出库了多少
a.出库数量 - b.库存 - isnull((select sum(入库数量) from #tmp
where 物料 = a.物料 and 出库日期 = a.出库日期 and 入库日期 < a.入库日期 and 入库日期 >
(select min(入库日期) from #tmp where 物料 = a.物料 and 出库日期 = a.出库日期)),0)
end
END,
a.入库日期 AS A表日期 ,
a.出库日期 AS B表日期
FROM #tmp AS a LEFT JOIN #tmp2 AS b ON
a.出库日期 = isnull((select min(出库日期) from #tmp2 where 物料 = b.物料 and 出库日期 > b.出库日期), ' ')
----清除测试环境
drop table #tmp,#tmp2
/*结果
物料 数量 A表日期 B表日期
---------- ----------- ---------- ------------
A001 80 2005-05-05 2005-05-08
A001 20 2005-05-05 2005-05-09
A001 120 2005-05-06 2005-05-09
A001 5 2005-05-07 2005-05-09
B001 10 2005-05-06 2005-05-10
C001 NULL NULL 2005-05-09
*/
[解决办法]
hellowork(一两清风):
结果有点不对
对不上的部分都没了
------解决方案--------------------
mark
[解决办法]
Haiwer(海阔天空) :
哪里?
[解决办法]
因为是对出库进行先入先出拆分,所以如果某个物料没有出库记录,那么即使该物料有入库记录也不会显示出来的.
上面回复的结果如果显示出被拆分的出库数量,则看起来效果更直接一些:
物料 出库数量 拆分数量 入库日期 出库日期
------------------------
A001 80 80 2005-05-05 2005-05-08
A001 145 20 2005-05-05 2005-05-09 /*145被拆分为20,120,5*/
A001 145 120 2005-05-06 2005-05-09
A001 145 5 2005-05-07 2005-05-09
B001 10 10 2005-05-06 2005-05-10
C001 10 NULL NULL 2005-05-09
[解决办法]
学习
[解决办法]
这个数据计算真是毫无规则,呵呵
[解决办法]
能把计算说明白么?
[解决办法]
好象是库存计算似的
[解决办法]
楼主最好解释一下,问题描述不清!
[解决办法]
A001 130 2005-05-07 null
B001 90 2005-05-06 null
C001 10 null 2005-05-09
他这个并非出库(单方向),而是两表对数(双方向)
[解决办法]
真是孤陋寡闻了,看了半天实在没看懂结果是怎么算出来的,也没看出两个表到底是什么关系。
[解决办法]
A表出貨,B表進貨.先進先出
需要寫個存儲過程
[解决办法]
先入先出是指在出库时,必须从最早的入库开始取,如果不够则再从下一入库中开始取,如果还不够则再从下一入库中取,如此类推...,所以一次出库的物料中可能来自多个入库.
楼主的要求就是求出每次出库的物料都来自哪些入库,从每个入库中取了多少.
以物料A001来说明先进先出的过程:
入库表:
物料 入库数量 入库日期
---------- ----------- ----------
A001 100 2005-05-05
A001 120 2005-05-06
A001 135 2005-05-07
B001 100 2005-05-06
出库表:
物料 出库数量 出库日期
---------- ----------- ----------
A001 80 2005-05-08
A001 145 2005-05-09
B001 10 2005-05-10
C001 10 2005-05-09
第一次出库是在2005-05-08,出库80,按照先进先出原则,这80应该来自2005-05-05,
该日入库了100.从该批入库中减掉80(该批A001还剩20).
第二次出库是在2005-05-09,出库145:
由于2005-05-05入库的中还剩余20,首先取该剩下的20,至此,出库还差145-20 = 125;
2005-05-06入库120,这120仍不够125,所以该批入库全部出库,还差5;
2005-05-07入库135,这135大于5,所以从该批入库中取5.
由此,2005-05-09出库的145个A001是由以下入库来构成的:
从2005-05-05入库的100中取20(另80已被2005-05-08的出库取走),还差145-20=125
从2005-05-06入库的120中取120(120不足够125,所以全出库),还差125-120=5
从2005-05-07入库的135中取5,还差5-5 = 0
[解决办法]
不要用入库出库来理解
可以用应收帐和客户缴款,而且客户可能预先付款的方式来理解
也可以用采购计划和生产计划的量比较来理解
[解决办法]
看回复才看懂题意。
楼上 和 楼上的楼上 两位老大厉害
[解决办法]
mark一下,都是强人
[解决办法]
hellowork(一两清风)
能具体说说构造2个临时表的那2段代码吗?我不是很理解