使用SQL查询拆分订单

时间:2016-08-01 17:29:54

标签: sql oracle

SQL初学者在这里。

由于我的问题很难解释,我会尝试用Excel来说明它:

enter image description here

有些供应商,每个供应商都有不同的供应商数量,可以提供一定的重量。 由于一辆卡车只能运输24吨,我喜欢带桌子 按24的价值拆分的订单。 所以30吨意味着2个不同的订单,一个24吨,一个6吨。

您是否知道使用SQL查询解决此问题?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

使用递归因子子查询的解决方案:

with 
     inputs ( supplier_number, order_weight ) as (
       select  1, 10 from dual union all
       select  2, 25 from dual union all
       select  3, 88 from dual
     ),
     r ( supplier_number, shipment_number, order_weight, weight_remaining ) as (
       select  supplier_number, 0, null, order_weight 
         from  inputs
       union all
       select  supplier_number, shipment_number + 1, least(24, weight_remaining),
               greatest(0, weight_remaining - 24)
         from  r
         where weight_remaining != 0
     )
select   supplier_number, shipment_number, order_weight
from     r
where    shipment_number > 0
order by supplier_number, shipment_number
;




SUPPLIER_NUMBER SHIPMENT_NUMBER ORDER_WEIGHT
--------------- --------------- ------------
              1               1           10
              2               1           24
              2               2            1
              3               1           24
              3               2           24
              3               3           24
              3               4           16

答案 1 :(得分:1)

你可以使用recursive subquery factoring(假设你是11gR2或更高):

with r (supplier_number, order_weight, truck_number, truck_weight, remaining_weight) as (
  select supplier_number, order_weight, 1,
    least(order_weight, 24), order_weight - 24
  from t
  union all
  select supplier_number, order_weight, truck_number + 1,
    least(remaining_weight, 24), remaining_weight - 24
  from r
  where remaining_weight > 0
)
select supplier_number, order_weight, truck_number, truck_weight
from r
order by supplier_number, truck_number;

SUPPLIER_NUMBER ORDER_WEIGHT TRUCK_NUMBER TRUCK_WEIGHT
--------------- ------------ ------------ ------------
              1           10            1           10
              2           25            1           24
              2           25            2            1
              3           88            1           24
              3           88            2           24
              3           88            3           24
              3           88            4           16

锚定成员使用the least() function获得原始重量,如果它高于原始重量,则为24,这就是卡车编号1中的重量;并找出剩下的东西(这里可能是负面的,因为它无关紧要)。如果递归成员大于零,则递归成员对前一级别的余数重复计算。

答案 2 :(得分:1)

您可以使用数字表格执行此操作。我假设你有一个:

select t.*, n.n,
       (case when n.n * 24 <= t.tons then 24
             else mod(t.tons, 24)
        end)
from t join
     numbers n
     on (n.n - 1) * 24 < t.tons;

如果你的表足够大,这是生成数字表的一种简单方法:

with numbers as (
      select rownum as n
      from t
     )