我有一个奇怪的要求。
说我有两张桌子:
ORDER_TB
SEQ PRODUCT_ID ORDER_QTY
1 1 1
2 1 1
3 1 1
STOCK_TB
LOCATION STOCK_QTY
A1 2
B1 1
Desired Join Result:
PRODUCT_ID ORDER_QTY ASSIGNED_LOCATION
1 1 A1
1 1 A1
1 1 B1
换句话说,我希望根据库存数量,在stock_tb中为每个产品分配一个位置。
这对我来说看起来不像是一套操作。是否可以使用连接或在解决此问题时是否还有其他干净的替代方案?
答案 0 :(得分:0)
您需要做的是获取每列的累计总和 - 这为您提供每个值的第一个和最后一个订单。然后你可以在范围内进行连接。
with o as (
select o.*, cumesum
from ORDER_TB o OUTER APPLY
(select sum(o2.order_qty) as cumesum
from ORDER_TB o2
where o2.seq <= o.seq
) o2
),
s as (
select s.*, s2.cumeqty
from STOCK_TB s outer apply
(select sum(s2.order_qty) as cumeqty
from STOCK_TB
where s2.location <= s.location
) s2
)
select o.*, s.location
from o join
s
on o.cumesum between s.cumeqty - s.order_qty + 1 and s.cumeqty;
注意:这适用于您提供的数据。但是,如果两个表中的数量不对齐,则逻辑会更复杂。
答案 1 :(得分:0)
另一种方法是使用分析函数:
with cum as
(select s.*, sum(stock_qty) over(order by location) as cum_qty
from stock_tb s)
select x.product_id, x.order_qty, y.location as assigned_location
from (select o.*,
row_number() over(partition by product_id order by seq) as curr_qty
from order_tb o) x
cross join cum y
where y.cum_qty =
(select min(z.cum_qty) from cum z where z.cum_qty >= x.curr_qty)
or (not exists (select 1 from cum z where z.cum_qty > x.curr_qty) and
y.cum_qty = x.curr_qty)
order by seq