"完全外连接""和子查询

时间:2017-02-17 13:25:55

标签: sql oracle join subquery outer-join

我有一个完整的外连接查询,其中包含oracle中的case和sub查询。我想要完成的是汇总同一表中的当前年度数据和上一年的数据,以便进行比较。但是,我的FULL OUTER JOIN充当内部联接,不返回当前年份和上一年的空值。

这是我的代码:

SELECT
   SQ1.CHANNEL,
   SQ1.SHORT,
   SQ1.NAME,
   SQ1.RDC,
   SQ1.CY_APPROVED_COUNT,
   SQ2.PY_APPROVED_COUNT,
   SQ1.CY_APPROVED_VOLUME,
   SQ2.PY_APPROVED_VOLUME,
   SQ1.CY_DECLINED_COUNT,
   SQ2.PY_DECLINED_COUNT,
   SQ1.CY_DECLINED_VOLUME,
   SQ2.PY_DECLINED_VOLUME,
   SQ1.CY_RETURNED_COUNT,
   SQ2.PY_RETURNED_COUNT,
   SQ1.CY_RETURNED_VOLUME,
   SQ2.PY_RETURNED_VOLUME
FROM ( SELECT 
          CHANNEL,
          SHORT,
          NAME,
          RDC,
          SUM (CASE WHEN STATUS = 'Approved' THEN  APP_COUNTS ELSE 0 END) AS CY_APPROVED_COUNT,
          SUM (CASE WHEN STATUS = 'Approved' THEN  PROJ_VOL ELSE 0 END) AS CY_APPROVED_VOLUME,
          SUM (CASE WHEN STATUS = 'Declined' THEN  APP_COUNTS ELSE 0 END) AS CY_DECLINED_COUNT,
          SUM (CASE WHEN STATUS = 'Declined' THEN  PROJ_VOL ELSE 0 END) AS CY_DECLINED_VOLUME,
          SUM (CASE WHEN STATUS = 'Returned' THEN  APP_COUNTS ELSE 0 END) AS CY_RETURNED_COUNT,
          SUM (CASE WHEN STATUS = 'Returned' THEN  PROJ_VOL ELSE 0 END) AS CY_RETURNED_VOLUME
       FROM WFRT_MSP_SP_MTD
       WHERE PERIOD >= TO_DATE('2016/02/01', 'yyyy/mm/dd')
         AND PERIOD <= TO_DATE('2016/02/13','yyyy/mm/dd')
         AND CHANNEL = 'MSP'
         AND RDC = 'BASE'
       GROUP BY 
          CHANNEL,
          SHORT,
          NAME,
          RDC 
) SQ1
-- NOT CORRECTLY SHOWING NULL VALUES
FULL OUTER JOIN  

( SELECT 
     CHANNEL,
     SHORT,
     NAME,
     RDC,
     SUM (CASE WHEN STATUS = 'Approved' THEN  APP_COUNTS ELSE 0 END) AS PY_APPROVED_COUNT,
     SUM (CASE WHEN STATUS = 'Approved' THEN  PROJ_VOL ELSE 0 END) AS PY_APPROVED_VOLUME,
     SUM (CASE WHEN STATUS = 'Declined' THEN  APP_COUNTS ELSE 0 END) AS PY_DECLINED_COUNT,
     SUM (CASE WHEN STATUS = 'Declined' THEN  PROJ_VOL ELSE 0 END) AS PY_DECLINED_VOLUME,
     SUM (CASE WHEN STATUS = 'Returned' THEN  APP_COUNTS ELSE 0 END) AS PY_RETURNED_COUNT,
     SUM (CASE WHEN STATUS = 'Returned' THEN  PROJ_VOL ELSE 0 END) AS PY_RETURNED_VOLUME
FROM WFRT_MSP_SP_MTD
WHERE PERIOD >= TO_DATE('2015/02/01', 'yyyy/mm/dd')
   AND PERIOD <= TO_DATE('2015/02/13','yyyy/mm/dd')
   AND CHANNEL = 'MSP'
   AND RDC = 'BASE'
GROUP BY 
   CHANNEL,
   SHORT,
   NAME,
   RDC
) SQ2
ON sq1.short = sq2.short
;

如果可以,请帮忙。

1 个答案:

答案 0 :(得分:2)

只需使用条件聚合:

SELECT CHANNEL, SHORT, NAME, RDC,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Approved' THEN  APP_COUNTS ELSE 0 END) AS CY_APPROVED_COUNT,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Approved' THEN  PROJ_VOL ELSE 0 END) AS cY_APPROVED_VOLUME,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Declined' THEN  APP_COUNTS ELSE 0 END) AS CY_DECLINED_COUNT,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Declined' THEN  PROJ_VOL ELSE 0 END) AS CY_DECLINED_VOLUME,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Returned' THEN  APP_COUNTS ELSE 0 END) AS CY_RETURNED_COUNT,
       SUM(CASE WHEN this_year = 1 AND STATUS = 'Returned' THEN  PROJ_VOL ELSE 0 END) AS CY_RETURNED_VOLUME,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Approved' THEN  APP_COUNTS ELSE 0 END) AS PY_APPROVED_COUNT,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Approved' THEN  PROJ_VOL ELSE 0 END) AS PY_APPROVED_VOLUME,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Declined' THEN  APP_COUNTS ELSE 0 END) AS PY_DECLINED_COUNT,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Declined' THEN  PROJ_VOL ELSE 0 END) AS PY_DECLINED_VOLUME,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Returned' THEN  APP_COUNTS ELSE 0 END) AS PY_RETURNED_COUNT,
       SUM(CASE WHEN prev_year = 1 AND STATUS = 'Returned' THEN  PROJ_VOL ELSE 0 END) AS PY_RETURNED_VOLUME
FROM (SELECT msm.*,
             (CASE WHEN PERIOD >= DATE '2015-02-01' AND
                        PERIOD <= '2015-02-13'
                   THEN 1 ELSE 0
              END) as prev_year,
             (CASE WHEN PERIOD >= DATE '2016-02-01' AND
                        PERIOD <= '2016-02-13'
                   THEN 1 ELSE 0
              END) as this_year
      FROM WFRT_MSP_SP_MTD msm
     ) msm
WHERE CHANNEL = 'MSP' AND RDC = 'BASE'
GROUP BY CHANNEL, SHORT, NAME, RDC;