目录
0 需求描述
1 数据准备
2 问题分析
3 小结
累计到货数量计算
出货数量计算
剩余数量计算
0 需求描述
假设现有多种商品的订单需求表 DEMO_REQUIREMENT,以及商品的到货队列表 DEMO_ARR_QUEUE,要求按照业务需要,设计一个报表,展示出每种商品的到货队列,并给出每次到货应直接出货多少数量,出货后剩余多少数量,直到某批到货满足订单需求则不再统计该商品的出货计划。
1 数据准备
-- 创建商品需求表并插入示例数据
CREATE TABLE demo_requirement (
item_id INT,
req_qty INT
);
INSERT INTO demo_requirement VALUES-- 创建商品需求表并插入示例数据
CREATE TABLE demo_requirement (
item_id INT,
req_qty INT
);
INSERT INTO demo_requirement VALUES
(1, 60),
(2, 100),
(3, 80),
(4, 90);
-- 创建商品到货队列表并插入示例数据
CREATE TABLE demo_arr_queue (
arr_id INT,
item_id INT,
arr_qty INT
);
INSERT INTO demo_arr_queue VALUES
(10, 1, 60),
(11, 1, 50),
(12, 2, 40),
(13, 2, 60),
(14, 3, 20),
(15, 3, 50),
(16, 3, 50),
(17, 4, 40),
(18, 4, 40);
2 问题分析
步骤1:每个商品每次到货的累计到货数量及对应需求数量
-- 计算每个商品每次到货时累计到货数量以及对应需求数量(通过连接获取),作为中间结果展示
SELECT
daq.item_id,
daq.arr_id,
daq.arr_qty,
SUM(daq.arr_qty) OVER (PARTITION BY daq.item_id ORDER BY daq.arr_id) AS cumulative_arrival_qty,
dr.req_qty
FROM
demo_arr_queue daq
-- 左连接商品需求表,以便获取每个商品的需求数量
LEFT JOIN demo_requirement dr ON daq.item_id = dr.item_id
ORDER BY
daq.item_id,
daq.arr_id;
item_id | arr_id | arr_qty | cumulative_arrival_qty | req_qty |
---|---|---|---|---|
1 | 10 | 60 | 60 | 60 |
1 | 11 | 50 | 110 | 60 |
2 | 12 | 40 | 40 | 100 |
2 | 13 | 60 | 100 | 100 |
3 | 14 | 20 | 20 | 80 |
3 | 15 | 50 | 70 | 80 |
3 | 16 | 50 | 120 | 80 |
4 | 17 | 40 | 40 | 90 |
4 | 18 | 40 | 80 | 90 |
这个中间结果展示了每个商品每次到货的基本信息(到货批次 ID、到货数量),以及通过窗口函数计算出的累计到货数量,还有通过左连接获取到的对应商品需求数量,方便后续基于这些数据去进一步计算出货量和剩余数量。
步骤2:基于中间结果计算出货量和剩余量
-- 基于前面的中间结果进一步计算出货量和剩余量,展示最终结果
SELECT
sub.item_id,
sub.arr_id,
sub.arr_qty,
-- 计算出货数量
CASE
WHEN sub.cumulative_arrival_qty <= sub.req_qty
THEN LEAST(sub.arr_qty, sub.req_qty - (sub.cumulative_arrival_qty - sub.arr_qty))
ELSE 0
END AS shipment_quantity,
-- 计算剩余数量
CASE
WHEN sub.cumulative_arrival_qty < sub.req_qty
THEN sub.req_qty - sub.cumulative_arrival_qty
WHEN sub.cumulative_arrival_qty = sub.req_qty
THEN 0
ELSE sub.cumulative_arrival_qty - sub.req_qty
END AS remaining_quantity
FROM (
-- 这里是前面计算累计到货数量和获取需求数量的中间结果
SELECT
daq.item_id,
daq.arr_id,
daq.arr_qty,
SUM(daq.arr_qty) OVER (PARTITION BY daq.item_id ORDER BY daq.arr_id) AS cumulative_arrival_qty,
dr.req_qty
FROM
demo_arr_queue daq
LEFT JOIN demo_requirement dr ON daq.item_id = dr.item_id
ORDER BY
daq.item_id,
daq.arr_id
) sub
ORDER BY
sub.item_id,
sub.arr_id;
item_id | arr_id | arr_qty | shipment_quantity | remaining_quantity |
---|---|---|---|---|
1 | 10 | 60 | 60 | 0 |
1 | 11 | 50 | 0 | 50 |
2 | 12 | 40 | 40 | 60 |
2 | 13 | 60 | 60 | 0 |
3 | 14 | 20 | 20 | 60 |
3 | 15 | 50 | 50 | 10 |
3 | 16 | 50 | 10 | 40 |
4 | 17 | 40 | 40 | 50 |
4 | 18 | 40 | 40 | 10 |
3 小结
本文主要的思路如下:
累计到货数量计算
使用窗口函数
运用 SUM
函数结合 OVER
子句来计算每个商品的累计到货数量。具体而言,在对 DEMO_ARR_QUEUE
表进行查询时,通过 PARTITION BY
按照商品 ID(item_id
)对数据进行分区,这样就可以针对每个商品独立地进行计算。然后使用 ORDER BY
按照到货批次 ID(arr_id
)进行排序,确保累计计算是按照到货的先后顺序进行的。例如:
SUM(arr_qty) OVER (PARTITION BY item_id ORDER BY arr_id) AS cumulative_arrival_qty
- 这个表达式会为每个商品的每一行数据计算出从第一行到当前行的到货数量总和,也就是累计到货数量。
出货数量计算
条件判断逻辑
首先进行一个主要的条件判断,即比较当前商品的累计到货数量(cumulative_arrival_qty
)与订单需求数量(req_qty
)的大小关系。使用 CASE WHEN
语句来实现:
CASE
WHEN cumulative_arrival_qty <= req_qty
- 如果累计到货数量小于等于订单需求数量,说明还未完全满足订单或者刚好满足订单。此时,出货数量的计算需要进一步考虑当前到货数量(
arr_qty
)和订单需求剩余数量。订单需求剩余数量可以通过订单需求数量减去之前已经累计到货但未出货的数量得到,即req_qty - (cumulative_arrival_qty - arr_qty)
。然后使用LEAST
函数取当前到货数量和订单需求剩余数量中的较小值作为出货数量:
THEN LEAST(arr_qty, req_qty - (cumulative_arrival_qty - arr_qty))
- 如果累计到货数量大于订单需求数量,说明订单已经满足,此时出货数量为 0:
ELSE 0
END AS shipment_quantity
剩余数量计算
分情况处理
同样使用 CASE WHEN
语句来处理不同情况。
当累计到货数量小于订单需求数量时,剩余数量就是订单需求数量减去累计到货数量:
CASE
WHEN cumulative_arrival_qty < req_qty
THEN req_qty - cumulative_arrival_qty
- 当累计到货数量等于订单需求数量时,剩余数量为 0:
WHEN cumulative_arrival_qty = req_qty
THEN 0
- 当累计到货数量大于订单需求数量时,剩余数量为累计到货数量减去订单需求数量:
ELSE cumulative_arrival_qty - req_qty
END AS remaining_quantity
如果您觉得本文还不错,对你有帮助,那么不妨可以关注一下我的数字化建设实践之路专栏,这里的内容会更精彩。
专栏 原价99,现在活动价59.9,按照阶梯式增长,还差5个人上升到69.9,最终恢复到原价。
专栏优势:
(1)一次收费持续更新。
(2)实战中总结的SQL技巧,帮助SQLBOY 在SQL语言上有质的飞越,无论你应对业务难题及面试都会游刃有余【全网唯一讲SQL实战技巧,方法独特】
SQL很简单,可你却写不好?每天一点点,收获不止一点点-CSDN博客
(3)实战中数仓建模技巧总结,让你认识不一样的数仓。【数据建模+业务建模,不一样的认知体系】(如果只懂数据建模而不懂业务建模,数仓体系认知是不全面的
(4)数字化建设当中遇到难题解决思路及问题思考。
我的专栏具体链接如下
数字化建设通关指南_莫叫石榴姐的博客-CSDN博客