【问题标题】:Subtracting Running Total until 0减去运行总计直到 0
【发布时间】:2019-05-20 04:20:30
【问题描述】:

我正在尝试对我的avail_relief_amt 列进行减法运算。目标是使(qty_filled / qty_total) 尽可能接近100%,这就是room_to_improve 列的用途。

当前查询:

    SELECT
    t2_date,
    part_no,
    issue_group,
    level,
    p_category,
    qty_filled,
    qty_total,
    relief_amt,
    curr_mth_note,
    carryover_note,
    room_to_improve,
    avail_relief_amt,
    CASE
        WHEN avail_relief_amt != 0 THEN ( qty_total - room_to_improve )
        ELSE NULL
    END AS new_qty_total
FROM
    (
        SELECT
            t2_date,
            part_no,
            issue_group,
            level,
            p_category,
            qty_filled,
            qty_total,
            relief_amt,
            curr_mth_note,
            carryover_note,
            CASE
                WHEN qty_filled < qty_total THEN ( qty_total - qty_filled )
                ELSE NULL
            END AS room_to_improve,
            avail_relief_amt
        FROM
            (
                SELECT
                    t2_date,
                    part_no,
                    issue_group,
                    level,
                    p_category,
                    qty_filled,
                    qty_total,
                    relief_amt,
                    curr_mth_note,
                    carryover_note,
                    CASE
                        WHEN curr_mth_note IS NOT NULL THEN relief_amt
                        ELSE NULL
                    END AS avail_relief_amt
                FROM
                    (
                        SELECT
                            t1.t2_date,
                            t1.part_no,
                            t1.issue_group,
                            t1.level,
                            t1.p_category,
                            t1.qty_filled,
                            t1.qty_total,
                            mv.relief_amt,
                            mv.curr_mth_note,
                            mv.carryover_note
                        FROM
                            table_detail_mv mv,
                            table_part_con t1
                        WHERE
                            t1.part_no = mv.part_no
                            AND t1.t2_date = mv.t2_date
                        GROUP BY
                            t1.t2_date,
                            t1.issue_group,
                            t1.level,
                            t1.part_no,
                            t1.p_category,
                            t1.qty_filled,
                            t1.qty_total,
                            mv.relief_amt,
                            mv.curr_mth_note,
                            mv.carryover_note
                        ORDER BY
                            t1.t2_date,
                            t1.issue_group,
                            t1.level DESC
                    )
            )
    )
ORDER BY
    t2_date,
    part_no,
    issue_group,
    level DESC

当前输出:

avail_relief_amt 列以relief_amt 列中的任何数字开头。如果avail_relief_amt &gt; room_to_improve 下一个avail_relief_amt 应该是(avail_relief_amt - room_to_improve) 剩下的任何内容。在我上面的输出中,由于第 2 行没有room_to_improve,所以它需要向下到下一行,等等,直到avail_relief_amt = 0

期望的输出:

编辑

我已从上述查询中删除了 room_to_improveavail_relief_amtnew_qty_total 列,因为它们只是为了帮助可视化我的最终目标而添加的。

当前输出(不含上列):

对最终目标的更好解释:

  • 获取qty_total / qty_filled 尽可能接近100%,方法是从relief_amt 获取直到等于0。
  • relief_amt 将沿着优先级排序(忽略“迟到”)。 优先顺序为 (issue_group='1', s_level='80') - (issue_group='1', s_level='100') - (issue_group='2/3 ', s_level='80') - (issue_group='2/3 ', s_level='100')
  • 使用上述输出,需要 27 个才能生成 qty_total = qty_filled,因此该数字从 relief_amt(共 57 个)中删除。离开relief_amt=30
  • 然后查询跳到下一个优先级,但是由于94 = 94,没有relief_amt需要使用,所以它跳到下一行(记住跳过'Late')。李>
  • 现在我们需要得到qty_total=226,更接近qty_filled=125,但我们只有一个relief_amt=30。所以剩下的relief_amt 是从那个qty_total=226 中取出来的,变成了新的qty_total=196,然后我们就没有了relief_amt

我知道这非常令人困惑,并且由于所有变量和正在发生的重复方程,我和我的同事都非常困惑。

任何帮助都会很棒!

【问题讨论】:

  • 是否有任何列显示行的读取顺序?
  • @Error_2646 是的...抱歉,出于保密目的,我尝试编辑我的代码并忘记将其包含在内。它们将按日期、部分、问题组、p_category 和级别进行分区。 qty_total 列按级别分组
  • @KassieB 如果您提供数据样本以优化查询,将会有所帮助。

标签: sql oracle case cumulative-sum


【解决方案1】:

我有一个解决方案,但由于您没有原始数据,我的解决方案将您的查询用作视图。

因此,您必须使用以下语法创建视图:

create view currentOutput as select ...your current query here... ;

此外,您需要一个日期字段,我认为它的名称类似于 dateEntry

然后您可以执行以下操作:

 SELECT dateEntry,
       room_to_improve,
       CASE
           WHEN temp.AVAIL_RELIEF_AMT - NVL(SUMPREVIOUSROOMTOIMPROVE, 0) < 0 THEN 0
           ELSE temp.AVAIL_RELIEF_AMT - NVL(SUMPREVIOUSROOMTOIMPROVE, 0)
       END AS AVAIL_RELEIF_AMT,
       new_qty_total
FROM
  ( SELECT c1.*,

     (SELECT sum(room_to_improve)
      FROM currentOutput
      WHERE dateEntry < c1.dateEntry) AS sumPreviousRoomToImprove
   FROM currentOutput c1
   ORDER BY dateEntry )TEMP ;

结果:

DATEENTRY -ROOM_TO_IMPROVE-   AVAIL_RELEIF_AMT-   NEW_QTY_TOTAL-
1-    27  -57-    67
2-        -30-    
3-    101-    -30-    125
4-    49- 0-  177-

小提琴:https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=2c074fe2adc232fd596d623e1cee8123

【讨论】:

  • 我已经更新了查询以显示我到目前为止所拥有的全部内容。
  • @KassieB 试试当前的解决方案,告诉我它是否是您想要的结果。我会尝试重新访问这个。我基本上所做的技巧是从当前条目之前获取所有条目,然后进行总和。然后你从电流中减去这个总和。如果结果为负,则转换为零。
  • 我一直在努力让它发挥作用,但这是一个非常棘手的计算,以至于我(以及迄今为止我要求帮助的同事)都在苦苦挣扎。我将编辑我的帖子并添加更好的数据视图,以及更好地解释我总体上要做什么,也许这可能有助于阐明一些问题。从技术上讲,我不需要 room_to_improveavail_relief_amtnew_qty_total 列……只是认为它们有助于可视化我的最终目标。
  • @KassieB 另一种选择是将它们作为列包含并使用更新语句来计算它们。但总的来说,获得所有先前 room_to_improve 的总和可能是一种方法。
  • 我刚刚在我最初的问题中添加了一个编辑部分,这有助于进一步分解我的最终目标。由于这 3 列只是我为了显示我的最终目标而进行的计算,因此可以将它们删除/操作为我需要的所有计算才能使所有这些工作。
猜你喜欢
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多