2017-02-17 2 views
0

У меня есть полный внешний запрос соединения с аргументом case и sub в oracle. То, что я пытаюсь выполнить, - агрегировать данные текущего года и данные за предыдущий год из той же таблицы, чтобы сравнить их. Однако мой FULL OUTER JOIN действует как внутреннее соединение, не возвращая нулевые значения как из текущего, так и за предыдущий год.Полное внешнее соединение с «case when» и подзапросом

Вот мой код:

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

Может помочь использовать некоторые отступы для удобства чтения –

ответ

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; 
+0

Я получаю ORA-00904: "MSM": недопустимый идентификатор 00904. 00000 - "% s: неверный идентификатор" – dmoses

+0

@dmoses просто перемещает псевдоним 'msm' только из-за закрывающей скобки подзапроса, внутри него (т. Е. Вам нужно псевдоним таблицы внутри подзапроса, а не самого подзапроса). – Boneist

+0

@Boneist Я переместил «msm» прямо рядом с таблицей в подзапросе «wfrt_msp_sp_mtd» и получил сообщение об ошибке «Литерал не соответствует строке формата» – dmoses

Смежные вопросы