我实际上正在努力为每一行分配数量编号。
示例:
每个容器的总数:29
由于某些原因,第一批的最大限制为10,第二批的最大限制为69
我试图像下面这样编写查询,但是返回错误。
select case when totalQ < 29.5 then Quantity else Quantity
end as Quantity, lotno, totalQ from (
select quantity - 29.5 as totalQ,
* from TestB where id in (
select id from TestA where id =20))A
但是,我期望如下所示:
有人可以帮我解决这个问题吗?
谢谢!
答案 0 :(得分:3)
尝试这样的事情:
create table TestB ( BatchID varchar(10), TotalQuantity int )
insert into TestB ( BatchID, TotalQuantity ) values
( 'A', 70 ), ( 'B', 10 ), ( 'C', 69 ), ( 'D', 100 ),
( 'E', 0 ), ( 'F', 29 ), ( 'G', 58 ), ( 'H', 200 )
; with
A as
( select BatchID,
case when TotalQuantity >= 29 then 29 else TotalQuantity end as Quantity,
case when TotalQuantity >= 29 then TotalQuantity - 29 else 0 end as Remaining
from TestB
union all
select BatchID,
case when Remaining >= 29 then 29 else Remaining end as Quantity,
case when Remaining >= 29 then Remaining - 29 else 0 end as Remaining
from A
where Remaining > 0 )
select BatchID,
Quantity
from A
order by BatchID,
Quantity desc
option ( MaxRecursion 1000 )
答案 1 :(得分:2)
大卫的答案非常好。这是使用SQL存储过程的更长的答案。
示例在这里:http://rextester.com/VUQXVQ46335
存储过程
create table test (batch varchar(20), quantity int);
insert into test values ('lot0', 29), ('lot1', 30), ('lot2', 28), ('lot3', 100);
go
create procedure CreateBatches (@BatchSize int)
as
begin
-- declare variables and create a temporary table
set nocount on
declare @v_batch varchar(20), @v_quantity int
create table #tempTest (batch varchar(20), quantity int)
-- loop through all records
declare testCursor cursor for select * from test
open testCursor
fetch next from testCursor into @v_batch, @v_quantity
-- process each record
while @@fetch_status = 0
begin
-- if quantity is larger than the bucket, insert the batch size in the table
-- reduce the quantity and continue looping
while @v_quantity > @BatchSize
begin
insert into #tempTest values (@v_batch, @BatchSize)
set @v_quantity = @v_quantity - @BatchSize
end
-- store the quantity lower than the batch size in the table
insert into #tempTest values (@v_batch, @v_quantity)
fetch next from testCursor into @v_batch, @v_quantity
end
select * from #tempTest
drop table #tempTest
close testCursor
deallocate testCursor
set nocount off
end;
go
结果
exec CreateBatches 32;
# batch quantity
1 lot0 29
2 lot1 30
3 lot2 28
4 lot3 32
5 lot3 32
6 lot3 32
7 lot3 4
另一次跑步
exec CreateBatches 29;
# batch quantity
1 lot0 29
2 lot1 29
3 lot1 1
4 lot2 28
5 lot3 29
6 lot3 29
7 lot3 29
8 lot3 13
此方法为您提供了一些灵活性,并且使您对批处理系统的工作原理有了更多的了解。处理大量数据时,存储过程可能会变慢。
比较
我对David的递归CTE和存储过程进行了比较。我创建了3031个批次/批次/记录,从第1个批次的500个数量开始,第2个批次的600个数量...第3031个批次的... 303500。
结果
结果以秒为单位。破折号表示查询在12秒后被中止。
Batch size CTE SP
---------- ----- -----
300000 1.46s 1.66s
200000 1.61s 1.88s
100000 2.27s 2.47s
50000 5.00s 5.41s
25000 7.71s 8.05s
12500 - -
这些只是对右旋糖酐的粗略结果测试。您可以看到存储过程比CTE慢。
答案 2 :(得分:0)
使用自我加入和联合
select t.batch,t.quantity from t join t t1 on t.batch=t1.batch
union
select t.batch,t.totalQ from t join t t1 on t.batch=t1.batch