Oracle SQL两表关联匹配价格 无最大匹配时取最近最小数量值
问题背景
现有两张业务数据表:
- 表1结构及样例数据:

- 表2结构及样例数据:

需求为将表2的Price字段按规则匹配追加到表1中,最终预期返回效果如下:
匹配规则
匹配优先级从高到低如下:
- 若表1记录的Quantity值在表2同Product_NR下存在完全匹配项,直接取对应Price;
- 若无完全匹配项,优先取表2中大于该Quantity的最近值对应的Price(例如Quantity为12时表2无对应值,最近大值为20,则取20对应的Price);
- 若不存在大于该Quantity的匹配值(即当前Quantity超过表2同Product_NR下的最大Quantity阈值),则取表2中小于该Quantity的最近值对应的Price,保证无数据遗漏。
现有代码问题
当前编写的查询仅实现了「优先匹配最近大值」的逻辑,未覆盖「无更大匹配值时取最近小值」的场景,会导致Product_NR为'20765'的记录丢失,原有代码如下:
select Product_NR, Customer, Quantity, min(price) from ( select distinct t1.Product_NR, t1.Customer, t1.Quantity, t2.price, min(t2.quantity) over (partition by t1.product_NR) as Quantity_min from Table_1 t1 left join Table_2 t2 on t1.Product_NR = t2.Product_NR and t1.Quantity <= t2.Quantity ) where t2.Quantity = Quantity_min group by Product_NR, Customer, Quantity
改造后代码
直接通过窗口函数按匹配优先级排序,取每条表1记录排序后的第一条匹配数据即可,无需拆分多分支判断,代码逻辑更简洁且覆盖全部场景:
SELECT Product_NR, Customer, Quantity, price FROM ( SELECT t1.Product_NR, t1.Customer, t1.Quantity, t2.price, ROW_NUMBER() OVER ( PARTITION BY t1.Product_NR, t1.Customer, t1.Quantity ORDER BY -- 优先级1:完全匹配 CASE WHEN t2.Quantity = t1.Quantity THEN 0 -- 优先级2:大于当前值的最近项 WHEN t2.Quantity > t1.Quantity THEN 1 -- 优先级3:小于当前值的最近项 ELSE 2 END, -- 同优先级下取Quantity差值最小的,即最近的值 ABS(t2.Quantity - t1.Quantity) ASC ) AS match_rank FROM Table_1 t1 LEFT JOIN Table_2 t2 ON t1.Product_NR = t2.Product_NR ) matched WHERE match_rank = 1
内容的提问来源于stack exchange,提问作者Es-Dot
相关产品推荐
相关产品推荐

