繁体   English   中英

如何在SQL中为每一行拆分数字?

[英]How to split the number for each row in SQL?

我实际上正在努力为每一行分配数量。

范例:

每个容器的总数量: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

在此处输入图片说明

但是,我期望如下所示:

在此处输入图片说明

有人可以帮我解决这个问题吗?

提前致谢!

尝试这样的事情:

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 )

大卫的答案很好。 这是使用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 ... 303500的600数量开始。

结果

结果以秒为单位。 破折号表示查询在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慢。

使用自我加入和联合

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM