Oracle 如何按月细分数据,并在没有数据的月份显示零?

Oracle 如何按月细分数据,并在没有数据的月份显示零?,oracle,oracle11g,Oracle,Oracle11g,使用表A中的信息,如何生成下表B中的结果 表A: CASE_ID DATE_EFF COPAY STATUS 1 11/04/2016 10 A 1 11/20/2016 5 A 1 11/23/2016 5 R 1 12/01/2016 1 A 1 12/10/2016 2 A

使用表A中的信息,如何生成下表B中的结果

表A:


CASE_ID     DATE_EFF      COPAY   STATUS
      1     11/04/2016    10      A
      1     11/20/2016    5       A
      1     11/23/2016    5       R
      1     12/01/2016    1       A
      1     12/10/2016    2       A
      1     12/12/2016    10      A
      1     12/31/2016    50      R

对于上述案例ID,我们的日期仅为2016年11月和2016年12月,但是,我想在以下6个月的时间段内对该案例ID进行细分,其中每个月的共同付款根据日期进行汇总,对于不在上述日期内的月份,输入零。此外,任何月份都只对状态为“a”的共付记录求和,因此在求和中忽略状态为“R”的记录。例如,根据上面表A中的数据,预期结果如下:

表B:


CASE_ID  MONTH     TOTAL_COPAY
1        01/2017   0
1        12/2016   13
1        11/2016   15
1        10/2016   0
1        09/2016   0
1        08/2016   0
下面是一个可能的解决方案[使用with子句],但是不使用with子句能实现吗?

可能的解决办法:

WITH
XRF AS
( SELECT CASE_ID, COPAY, DATE_EFF
    FROM Table_A WHERE STATUS = 'A'
)
SELECT F.CASE_ID, ST, NVL(SUM(F.COPAY),0) TOTAL_COPAY FROM XRF F PARTITION BY (F.CASE_ID)
            RIGHT OUTER JOIN (SELECT '12/2016' ST FROM DUAL UNION ALL
                    SELECT '11/2016' FROM DUAL UNION ALL
                                                  SELECT '10/2016' FROM DUAL UNION ALL
                                                  SELECT '09/2016' FROM DUAL UNION ALL
                                                  SELECT '08/2016' FROM DUAL UNION ALL
                                                  SELECT '07/2016' FROM DUAL) STS
                                                  ON (TO_CHAR(LAST_DAY((F.DATE_EFF)),'MM/YYYY') = STS.ST)
GROUP BY F.CASE_ID, ST ORDER BY F.CASE_ID, ST DESC
;
更新和解决方案: 使用上面的查询,我相信我已经回答了我自己的问题,实现了如下——不确定当您有数百万个这样的CASE_id记录时,使用这种方法是否昂贵。有什么想法吗

SELECT F.CASE_ID, ST, NVL(SUM(F.COPAY),0) TOTAL_COPAY FROM (SELECT CASE_ID, COPAY, DATE_EFF FROM TABLE_A WHERE STATUS = 'A') F PARTITION BY (F.CASE_ID)
            RIGHT OUTER JOIN (SELECT '12/2016' ST FROM DUAL UNION ALL
                    SELECT '11/2016' FROM DUAL UNION ALL
                                                  SELECT '10/2016' FROM DUAL UNION ALL
                                                  SELECT '09/2016' FROM DUAL UNION ALL
                                                  SELECT '08/2016' FROM DUAL UNION ALL
                                                  SELECT '07/2016' FROM DUAL) STS
                                                  ON (TO_CHAR(LAST_DAY((F.DATE_EFF)),'MM/YYYY') = STS.ST)
GROUP BY F.CASE_ID, ST ORDER BY F.CASE_ID, ST DESC
;

搜索
分区外部联接
您是如何决定该表将持续到2017年1月(而不是2016年12月或2017年2月)的?还是一个用户输入?@mathguy这是一个用户输入,更像是一个限制,所以是硬编码的。在这个特殊的案例中,我对8月16日到1月17日感兴趣。@MTO感谢您的建议。正在查看使用此实现。在不使用“with”子句的情况下,对上述解决方案有何帮助?如果可能的话,我希望将其作为一个代码。搜索
分区外部联接
您是如何决定该表将持续到2017年1月(而不是2016年12月或2017年2月)的?还是一个用户输入?@mathguy这是一个用户输入,更像是一个限制,所以是硬编码的。在这个特殊的案例中,我对8月16日到1月17日感兴趣。@MTO感谢您的建议。正在查看使用此实现。在不使用“with”子句的情况下,对上述解决方案有何帮助?如果可能的话,我想把它作为一个代码。