【问题标题】:how to calculate quota with analytic function row by row?如何使用分析函数逐行计算配额?
【发布时间】:2014-07-11 10:58:33
【问题描述】:

我们在 Oracle 中使用分析函数时遇到问题。

我们想从其他列中计算剩余配额列。我们的数据按 branch_id 和 region_id 分组。每个分支和区域都有一个配额值(例如 1077)。 如果配额值大于剩余配额值,我们不会更改剩余配额值。

我希望以下示例具有描述性。

我们创建了一个查询来计算剩余配额的总和,但我们失败了。

示例查询和结果

SELECT   CUSTOMER_NUM, BRANCH_ID, REGION_ID, TOTAL_QUOTA, QUOTA,
                 TOTAL_QUOTA - 
                 SUM (CASE
                           WHEN TOTAL_QUOTA - QUOTA < 0
                              THEN 0
                           ELSE QUOTA
                        END) OVER (PARTITION BY BRANCH_ID, REGION_ID ORDER BY BRANCH_ID,
                    REGION_ID,DESC)      
                     AS REMAINING_QUOTA                     
            FROM MY_TABLE
           WHERE BRANCH_ID = 723 AND REGION_ID = 822
        ORDER BY BRANCH_ID,
                 REGION_ID DESC

请帮助我们解决这个问题。

谢谢...

改进:

事实上,由于查询复杂性降低,我从表中丢弃了一些列。

我们的测试表有这些列。

  CUSTOMER_NUM        NUMBER,
  BRANCH_ID           NUMBER,
  ACCOUNT_NUM         NUMBER,
  TOTAL_QUOTA         NUMBER,
  QUOTA               NUMBER,
  REGION_ID           NUMBER,
  LOB_CODE            NUMBER,
  ESTIMATED_END_DATE  DATE,
  TOTAL_AMOUNT        NUMBER

我们在 SQLFiddle 中创建该表的数据结构。链接:http://sqlfiddle.com/#!4/94fe4/1/0

我原来的失败查询是:

SELECT   CUSTOMER_NUM, BRANCH_ID, REGION_ID,LOB_CODE,ESTIMATED_END_DATE,TOTAL_AMOUNT, TOTAL_QUOTA, QUOTA,
                 TOTAL_QUOTA -
                 SUM (CASE
                           WHEN TOTAL_QUOTA - QUOTA < 0
                              THEN 0
                           ELSE QUOTA
                        END) OVER (PARTITION BY BRANCH_ID, REGION_ID, LOB_CODE ORDER BY BRANCH_ID,
                    REGION_ID,
                    LOB_CODE,
                    ESTIMATED_END_DATE,
                    TOTAL_AMOUNT DESC)  
                     AS REMAINING_QUOTA              
            FROM TEST_TABLE
           WHERE BRANCH_ID = 723 AND REGION_ID = 822
                 AND LOB_CODE = 934
        ORDER BY BRANCH_ID,
                 REGION_ID,
                 LOB_CODE,
                 ESTIMATED_END_DATE,
                 TOTAL_AMOUNT DESC

我修改了您的解决方案查询,其中包括 GREATEST 功能。但这对我们来说还不够。如果剩余配额为负数,则使用此函数将此值设置为零。但是,如果剩余配额为负数,我们不想减少配额值。该值必须保持不变。

我们想得到如下查询的结果:(我们为正确的结果添加“or QUOTA between 471 and 472”行。实际上没有这样的行)

SELECT   CUSTOMER_NUM, BRANCH_ID, REGION_ID,LOB_CODE,ESTIMATED_END_DATE,TOTAL_AMOUNT, TOTAL_QUOTA, QUOTA,
                 TOTAL_QUOTA -
                 SUM (CASE
                           WHEN TOTAL_QUOTA - QUOTA < 0
                      or QUOTA between 471 and 472
                              THEN 0
                           ELSE QUOTA
                        END) OVER (PARTITION BY BRANCH_ID, REGION_ID, LOB_CODE ORDER BY BRANCH_ID,
                    REGION_ID,
                    LOB_CODE,
                    ESTIMATED_END_DATE,
                    TOTAL_AMOUNT DESC)  
                     AS REMAINING_QUOTA              
            FROM TEST_TABLE
           WHERE BRANCH_ID = 723 AND REGION_ID = 822
                 AND LOB_CODE = 934
        ORDER BY BRANCH_ID,
                 REGION_ID,
                 LOB_CODE,
                 ESTIMATED_END_DATE,
                 TOTAL_AMOUNT DESC

【问题讨论】:

    标签: sql oracle sum business-intelligence analytic-functions


    【解决方案1】:

    看起来基本查询是:

    SELECT CUSTOMER_NUM, BRANCH_ID, REGION_ID, TOTAL_QUOTA, QUOTA,
           TOTAL_QUOTA - SUM(QUOTA) OVER (PARTITION BY BRANCH_ID, REGION_ID
                                          ORDER BY BRANCH_ID, REGION_ID DESC
                                         ) AS REMAINING_QUOTA
    FROM MY_TABLE
    WHERE BRANCH_ID = 723 AND REGION_ID = 822
    ORDER BY BRANCH_ID, REGION_ID DESC;
    

    请注意,order by 子句不稳定,因为存在重复。最好有一些其他列,例如 iddatetime 值,它们可以真正使排序保持一致。

    您似乎担心剩余配额为负数。在计算之后处理。只需使用greatest()函数:

    SELECT CUSTOMER_NUM, BRANCH_ID, REGION_ID, TOTAL_QUOTA, QUOTA,
           GREATEST(0,
                    TOTAL_QUOTA - SUM(QUOTA) OVER (PARTITION BY BRANCH_ID, REGION_ID
                                                   ORDER BY BRANCH_ID, REGION_ID DESC
                                                  )
                   ) AS REMAINING_QUOTA
    FROM MY_TABLE
    WHERE BRANCH_ID = 723 AND REGION_ID = 822
    ORDER BY BRANCH_ID, REGION_ID DESC;
    

    【讨论】:

    • 感谢回复。但是您的答案不足以解决实际问题。我改进了我的问题。请看一下
    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    相关资源
    最近更新 更多