我遇到了一个要求,我需要编写sql查询,根据仓库等级和销售排名将库存从一个位置填充到另一个位置。 以下是场景: 我有一张桌子有剩余数量的产品A(表1) 我有另一张表,其中包含产品A的所需数量(预测)(表2)。
我需要将产品数量从(表1)A发送到(表2)B,根据它们的等级(对于A SOH_RNK,对于B SLS_RNK)
表1:
PROD_ID SOH_RNK QTY STORE_ID_A
A 1 30 30105
A 2 16 21168
A 3 10 21032
A 4 9 30118
A 9 6 30011
A 10 5 21190
A 13 2 21016
表2:
PROD_ID SLS_RNK Forcast_QTY STORE_ID_B
A 1 15 21005
A 2 10 30019
A 3 11 21006
A 4 16 30001
A 5 11 21015
A 6 7 21004
预期输出:
Store_ID_B Store_id_A Transferred_Qty_from_A
21005 30105 15
30019 30105 10
21006 30105 5
21006 21168 6
30001 30105 0
30001 21168 10
30001 21032 6
21015 30105 0
21015 21168 0
21015 21032 4
21015 30118 7
21004 30105 0
21004 21168 0
21004 21032 0
21004 30118 2
21004 30011 5
到目前为止,我已尝试过制作交叉连接,但没有多大帮助。我试图避免程序方法,因为它将逐行,我有2000万这样的记录。
答案 0 :(得分:1)
这个想法是确定两个表中的数量范围,然后根据这些范围连接两个表,以获得从源存储发送到目标存储的产品数量。
这是计算第一个表的范围的查询示例(第二个表的查询类似于此表):
select t1.*,
coalesce(sum( qty )
over ( order by soh_rnk
range between unbounded preceding and 1 preceding),
0) As range_start,
sum( qty ) over ( order by soh_rnk ) As range_end
from table1 t1
PROD_ID |SOH_RNK |QTY |STORE_ID_A |RANGE_START |RANGE_END |
--------|--------|----|-----------|------------|----------|
A |1 |30 |30105 |0 |30 |
A |2 |16 |21168 |30 |46 |
A |3 |10 |21032 |46 |56 |
A |4 |9 |30118 |56 |65 |
A |9 |6 |30011 |65 |71 |
A |10 |5 |21190 |71 |76 |
A |13 |2 |21016 |76 |78 |
现在,当两个表中的两个数据范围相互重叠时,我们可以连接两个表中的记录
可以在此处找到用于检查两个范围是否重叠的公式:http://www.soliantconsulting.com/blog/2016/03/determining-if-two-date-ranges-overlap
它是:NOT (EndA <= StartB or StartA >= EndB)
最后的查询:
WITH t1 AS (
select t1.*,
coalesce(sum( qty ) over ( order by soh_rnk range between unbounded preceding and 1 preceding),0) As range_start,
sum( qty ) over ( order by soh_rnk ) As range_end
from table1 t1
),
t2 As (
select t2.*,
coalesce(sum( forecast_qty ) over ( order by sls_rnk range between unbounded preceding and 1 preceding),0) As range_start,
sum( forecast_qty ) over ( order by sls_rnk ) As range_end
from table2 t2
)
SELECT
t1.store_id_a,
t2.store_id_b,
least( t1.range_end, t2.range_end ) - greatest( t1.range_start, t2.range_start ) As Transferred_Qty_from_A
FROM t1
join t2
-- NOT (EndA <= StartB or StartA >= EndB)
on not ( t1.range_end <= t2.range_start OR t1.range_start >= t2.range_end)
and t1.prod_id = t2.prod_id
order by soh_rnk, sls_rnk
;
此查询的结果是:
STORE_ID_A |STORE_ID_B |TRANSFERRED_QTY_FROM_A |
-----------|-----------|-----------------------|
30105 |21005 |15 |
30105 |30019 |10 |
30105 |21006 |5 |
21168 |21006 |6 |
21168 |30001 |10 |
21032 |30001 |6 |
21032 |21015 |4 |
30118 |21015 |7 |
30118 |21004 |2 |
30011 |21004 |5 |
不幸的是,我不知道如何在结果集中包含0
数量的记录(当没有产品从第1个商店转移到第2个商店时)。