22,209
社区成员
发帖
与我相关
我的任务
分享
已知型号A的成品库存是:2000
已知型号A的在线情况如下:
型号 步骤 工序 结存
A 1 开料 1520
A 25 成型 1560
A 30 包装 600
怎样通过SQL实现下面的结果:
型号 订单号 交期 订单数量 备注
A 01 2013/6-1 1000 成品:1000
A 02 2013/6-10 1400 包装:400(600);成品:1000
A 03 2013/6-10 1400 成型:1200(1560);包装:200;
备注栏的说明是这样的:先满足交期在前面的订单,比如当前A型号在库存里面有2000,则先拿出1000用于交订单01的货;还有剩余的交订单02的货,不够再从前一道工序中拿数量,满足02订单。
A 02 2013/6-10 1400 包装:400(600);成品:1000
上面的备注中的意思是:订单02在包装工序只需要400就可以满足,但产线上该工序有600,多出的200用来交下一张订单(如果有的话)。
if OBJECT_ID('tempdb..#tempA', 'u') is not null drop table #tempA;
go
create table #tempA( [型号] varchar(100), [步骤] varchar(100), [工序] varchar(100), [结存] varchar(100));
insert #tempA
select 'A','1','开料','1520' union all
select 'A','25','成型','1560' union all
select 'A','30','包装','600'
if OBJECT_ID('tempdb..#tempB', 'u') is not null drop table #tempB;
go
create table #tempB( [型号] varchar(100), [订单号] varchar(100), [交期] varchar(100), [订单数量] varchar(100), [备注] varchar(100));
insert #tempB
select 'A','01','2013/6-1','1000','成品:1000' union all
select 'A','02','2013/6-10','1400','包装:400(600);r成品:1000' union all
select 'A','03','2013/6-10','1400','成型:1200(1560);包装:200;'
--这种需要用单纯的SQL实现很难(sql是一次性处理,而你这2个表,都需要动态分次计算),建议用存储过程实现:
--select * from #tempA
--select * from #tempB
DECLARE @库存 INT
SET @库存 = 2000
DECLARE
@型号 VARCHAR(100),
@订单号 VARCHAR(100),
@订单数量 INT,
@备注 NVARCHAR(MAX),
@还差多少 INT,
@从工序中取 INT,
@工序 NVARCHAR(100)
DECLARE cursor_order CURSOR STATIC LOCAL FORWARD_ONLY READ_ONLY
FOR
SELECT 型号,订单号,订单数量
FROM #tempB
ORDER BY 型号, 订单号
OPEN cursor_order
FETCH NEXT FROM cursor_order INTO @型号, @订单号, @订单数量
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @还差多少 = @订单数量
SET @备注 = N''
IF(@库存 > 0) --库存优先
BEGIN
IF (@库存 >= @还差多少)
BEGIN
SET @备注 = N'成品:' + LTRIM(@订单数量)
SET @还差多少 = 0
SET @库存 = @库存 - @订单数量
END
ELSE
BEGIN
SET @备注 = N'成品:' + LTRIM(@库存)
SET @还差多少 = @订单数量 - @库存
SET @库存 = 0
END
END
WHILE(@还差多少 > 0)
BEGIN
SET @从工序中取 = 0
SELECT TOP(1) @从工序中取=结存, @工序=工序 FROM #tempA A WHERE a.型号 = @型号 AND 结存 > 0 ORDER BY 步骤 DESC
IF(@从工序中取 > 0)
BEGIN
IF(@从工序中取 >= @还差多少)
BEGIN
SET @备注 = @备注 + ';' + @工序 + N':' + LTRIM(@还差多少)
UPDATE #tempA SET 结存 = @从工序中取-@还差多少 WHERE 型号 = @型号 AND 工序 = @工序
SET @还差多少 = 0
END
ELSE
BEGIN
SET @备注 = @备注 + ';' + @工序 + N':' + LTRIM(@从工序中取)
UPDATE #tempA SET 结存 = 0 WHERE 型号 = @型号 AND 工序 = @工序
SET @还差多少 = @还差多少 - @从工序中取
END
END
END
UPDATE #tempB SET 备注 = (CASE LEFT(@备注,1) WHEN ';' THEN STUFF(@备注,1,1,'') ELSE @备注 END) WHERE 型号 = @型号 AND 订单号 = @订单号
FETCH NEXT FROM cursor_order INTO @型号, @订单号, @订单数量
END
CLOSE cursor_order
DEALLOCATE cursor_order
SELECT * FROM #tempB
/*
型号 订单号 交期 订单数量 备注
A 01 2013/6-1 1000 成品:1000
A 02 2013/6-10 1400 成品:1000;包装:400
A 03 2013/6-10 1400 包装:200;成型:1200
*/
[/quote]if OBJECT_ID('tempdb..#tempA', 'u') is not null drop table #tempA;
go
create table #tempA( [型号] varchar(100), [步骤] varchar(100), [工序] varchar(100), [结存] varchar(100));
insert #tempA
select 'A','1','开料','1520' union all
select 'A','25','成型','1560' union all
select 'A','30','包装','600'
if OBJECT_ID('tempdb..#tempB', 'u') is not null drop table #tempB;
go
create table #tempB( [型号] varchar(100), [订单号] varchar(100), [交期] varchar(100), [订单数量] varchar(100), [备注] varchar(100));
insert #tempB
select 'A','01','2013/6-1','1000','成品:1000' union all
select 'A','02','2013/6-10','1400','包装:400(600);r成品:1000' union all
select 'A','03','2013/6-10','1400','成型:1200(1560);包装:200;'
--这种需要用单纯的SQL实现很难(sql是一次性处理,而你这2个表,都需要动态分次计算),建议用存储过程实现:
--select * from #tempA
--select * from #tempB
DECLARE @库存 INT
SET @库存 = 2000
DECLARE
@型号 VARCHAR(100),
@订单号 VARCHAR(100),
@订单数量 INT,
@备注 NVARCHAR(MAX),
@还差多少 INT,
@从工序中取 INT,
@工序 NVARCHAR(100)
DECLARE cursor_order CURSOR STATIC LOCAL FORWARD_ONLY READ_ONLY
FOR
SELECT 型号,订单号,订单数量
FROM #tempB
ORDER BY 型号, 订单号
OPEN cursor_order
FETCH NEXT FROM cursor_order INTO @型号, @订单号, @订单数量
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @还差多少 = @订单数量
SET @备注 = N''
IF(@库存 > 0) --库存优先
BEGIN
IF (@库存 >= @还差多少)
BEGIN
SET @备注 = N'成品:' + LTRIM(@订单数量)
SET @还差多少 = 0
SET @库存 = @库存 - @订单数量
END
ELSE
BEGIN
SET @备注 = N'成品:' + LTRIM(@库存)
SET @还差多少 = @订单数量 - @库存
SET @库存 = 0
END
END
WHILE(@还差多少 > 0)
BEGIN
SET @从工序中取 = 0
SELECT TOP(1) @从工序中取=结存, @工序=工序 FROM #tempA A WHERE a.型号 = @型号 AND 结存 > 0 ORDER BY 步骤 DESC
IF(@从工序中取 > 0)
BEGIN
IF(@从工序中取 >= @还差多少)
BEGIN
SET @备注 = @备注 + ';' + @工序 + N':' + LTRIM(@还差多少)
UPDATE #tempA SET 结存 = @从工序中取-@还差多少 WHERE 型号 = @型号 AND 工序 = @工序
SET @还差多少 = 0
END
ELSE
BEGIN
SET @备注 = @备注 + ';' + @工序 + N':' + LTRIM(@从工序中取)
UPDATE #tempA SET 结存 = 0 WHERE 型号 = @型号 AND 工序 = @工序
SET @还差多少 = @还差多少 - @从工序中取
END
END
END
UPDATE #tempB SET 备注 = (CASE LEFT(@备注,1) WHEN ';' THEN STUFF(@备注,1,1,'') ELSE @备注 END) WHERE 型号 = @型号 AND 订单号 = @订单号
FETCH NEXT FROM cursor_order INTO @型号, @订单号, @订单数量
END
CLOSE cursor_order
DEALLOCATE cursor_order
SELECT * FROM #tempB
/*
型号 订单号 交期 订单数量 备注
A 01 2013/6-1 1000 成品:1000
A 02 2013/6-10 1400 成品:1000;包装:400
A 03 2013/6-10 1400 包装:200;成型:1200
*/