【问题标题】:Purchase order number to fulfil customer order number - SQL采购订单号以履行客户订单号 - SQL
【发布时间】:2021-12-21 15:18:04
【问题描述】:
order Qty Inventory Type
1001 -1 -1 Customer Order
1002 -1 -2 Customer Order
1003 -1 -3 Customer Order
1004 -1 -4 Customer Order
1005 -5 -9 Customer Order
1006 3 -6 Purchase Order
1007 6 0 Purchase Order

通过上表,我们能否找到满足客户订单的采购订单号。
示例:
order # Qty Inventory Type Purchase order # that will fulfil order
1001 -1 -1 Customer Order 1006
1002 -1 -2 Customer Order 1006
1003 -1 -3 Customer Order 1006
1004 -1 -4 Customer Order 1007
1005 -5 -9 Customer Order 1007
1006 3 -6 Purchase Order
1007 6 0 Purchase Order

SQL

SELECT *
        , CASE WHEN Inventory >= 0 THEN OrderNumber
               ELSE LEAD(CASE WHEN QTY > 0 THEN OrderNumber END) IGNORE NULLS
                    OVER(ORDER BY OrderNumber)
          END PurchaseOrderNoToFulfil
FROM OrderTable;

上述查询不跟踪已使用的采购订单。例如,它显示了客户订单 # 1004 和 1005 的采购订单 # 1006。由于 1006 只有 3 个可用数量,因此它可以满足订单 1003,但不能超过此数量。

更多上下文:
在订单 1001 上,库存为 -1(超卖)。订单 1002,库存为 -2,依此类推。在订单 1006 上,有一个数量为 3 的传入采购订单来履行之前的客户订单。但是3的数量最多只能完成1003个订单。1004和1005订单要等到1007 PO进来。

【问题讨论】:

  • 请添加您目前的查询以及您遇到问题的地方。
  • SELECT * , CASE WHEN Inventory >= 0 THEN OrderNumber ELSE LEAD(CASE WHEN QTY > 0 THEN OrderNumber END) IGNORE NULLS OVER(ORDER BY OrderNumber) END PurchaseOrderNoToFulfil FROM OrderTable;
  • 我还是不明白这里的规则/假设是什么。
  • 在订单 1001 上,库存为 -1(超卖)。订单 1002,库存为 -2,依此类推。在订单 1006 上,有一个数量为 3 的传入采购订单来履行之前的客户订单。但是3个的数量最多只能完成1003个订单。1004和1005订单要等到1007 PO进来。

标签: sql


【解决方案1】:

您可以使用递归 CTE:

with recursive orders as (
   select row_number() over (order by `order`) o, * from ords
),
cte(id, r_id, s) as (
    select min(o.o), o1.o, o.qty + o1.qty from orders o 
    join orders o1 on o1.qty + o.qty >= 0 where o.qty < 0 and o1.qty = (select min(o2.qty) from orders o2 where o2.qty > 0)
    union all
    select c.id + 1, case when c.s + o1.qty >= 0 or o3.o is null then c.r_id else o3.o end, 
        case when c.s + o1.qty >= 0 then c.s + o1.qty else c.s + o1.qty + o3.qty end 
    from cte c join orders o1 on c.id + 1 = o1.o 
    left join orders o3 on o3.o > c.r_id where c.id + 1 <= (select max(o2.o) from orders o2 where o2.qty < 0)
)
select o.*, c.r_id from orders o left join cte c on o.o = c.id

【讨论】:

  • 感谢您的回复。我得到以下错误。 SQL 编译错误:[O1.O] is not a valid group by expression
【解决方案2】:

我认为这给了我符合您要求的结果。也许你会发现它很有用。

with C as (
    select ordernum, -inventory as inventory,
        sum(-qty) over (order by ordernum) as fulfilled
    from O where "Type" = 'Customer Order'
), P as (
    select *, sum(qty) over (order by ordernum) as POed
    from O where "Type" = 'Purchase Order')
select ordernum, inventory, PO, POed
from C outer apply (
    select min(ordernum) as PO, min(POed) as POed from P where POed >= fulfilled
) oa

https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=25a4efd31efc0827940a83b8658eb2b2

用标量子查询重写:

with C as (
    select ordernum, -inventory as inventory,
        sum(-qty) over (order by ordernum) as fulfilled
    from O where "Type" = 'Customer Order'
), P as (
    select *, sum(qty) over (order by ordernum) as POed
    from O where "Type" = 'Purchase Order')
select ordernum, inventory,
    (select min(ordernum) as PO from P where POed >= fulfilled) as PO
from C

【讨论】:

  • 您好,Snowflake 不支持“外部应用”。是否有“外部应用”的替代方案。谢谢。
  • @rain_maker 可能只是把它变成一个标量子查询(如上)。我删除了你可能并不真正需要的第二列。
猜你喜欢
  • 2018-06-01
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多