暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL进阶技巧:如何计算商品需求与到货队列表进出计划?

会飞的一十六 2025-01-15
67

点击上方【蓝色】字体   关注我们


01 场景描述 

假设现有多种商品的订单需求表 DEMO_REQUIREMENT,以及商品的到货队列表 DEMO_ARR_QUEUE,要求按照业务需要,设计一个报表,展示出每种商品的到货队列,并给出每次到货应直接出货多少数量,出货后剩余多少数量,直到某批到货满足订单需求则不再统计该商品的出货计划。


 02 数据准备 


    -- 创建商品需求表并插入示例数据
    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
    (160),
    (2100),
    (380),
    (490);


    -- 创建商品到货队列表并插入示例数据
    CREATE TABLE demo_arr_queue (
        arr_id INT,
        item_id INT,
        arr_qty INT
    );


    INSERT INTO demo_arr_queue VALUES
    (10160),
    (11150),
    (12240),
    (13260),
    (14320),
    (15350),
    (16350),
    (17440),
    (18440);




    03 问题分析 

      步骤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


           04  小 结      

          累计到货数量计算

          使用窗口函数


          运用 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



                        往期精彩

                        指标体系建设:什么是虚荣指标?

                        SQL进阶技巧:如何分析双重职务问题?

                        其实数据分析,只是在筛选没有准备的人,写给正在求职的你们。。。

                        SQL进阶技巧:如何求解直接线上最多的点数?

                        数据科学与SQL:如何利用本福特法则识别财务数据造假?

                        解锁SQL无限可能:如何利用HiveSQL实现0-1背包问题?



                        会飞的一十六


                        扫描右侧二维码关注我们






                        点个【在看】 你最好看






                        点击“阅读原文”解锁更多知识~~

                        文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论