如何逐行计算分析函数的配额?

时间:2014-07-11 10:58:33

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

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

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

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

enter image description here

我们创建了一个查询来计算remaining_quota,其中包括按功能划分的余额,但是我们失败了。

示例查询和结果

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

enter image description here

请帮我们处理这个问题。

...谢谢

  

改进:

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

我们的测试表有这些列。

  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功能的解决方案查询。但这对我们来说还不够。使用此功能,如果剩余配额为负,则将此值设置为零。但是,如果剩余配额为负数,我们不希望降低配额值。该值必须保持不变。

我们想得到如下查询的结果:(我们在471和472之间添加“或QUOTA”行以获得正确的结果。实际上没有这样的行)

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

enter image description here

1 个答案:

答案 0 :(得分:2)

基本查询似乎是:

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;