Объединения: Как вернуть значения по умолчанию для пустой правой части левого внешнего объединения - PullRequest
4 голосов
/ 02 марта 2012

В моей БД Oracle у меня есть левое внешнее соединение для родительского рабочего заказа с его дочерним рабочим заказом. Затем я запускаю вычисление, выполняя SUM () некоторых дочерних значений. Я обертываю результаты из дочерних заказов в Nvl (), чтобы убедиться, что они будут правильно рассчитаны.

Это работает, , за исключением , когда нет родительских заказов для детей. В этом случае «нулевые значения», возвращаемые во время отображения, объясняются тем, что в соединении нет результатов, и, таким образом, получается, что Nvl ([fieldname], 0) не преобразует их в 0. Таким образом, когда я думаю, что сумма дочерние значения с родительскими значениями, они также возвращают ноль из-за добавления значения к нулевому значению.

Какой лучший способ обойти это? Это то, что можно обойти или это запах, что что-то не так с моим запросом в принципе?

Запрос

Извините, я не могу опубликовать настройки для этого в данный момент. Для этого конкретного заказа (жестко запрограммированного) «правая» часть объединения пуста, так как у родителя нет дочерних элементов, и поэтому отображает ноль.

SELECT *
FROM   (SELECT *
        FROM   R_PCR_ALLWOSANDTASKSSEPARATELY)WOINFO
       LEFT OUTER JOIN (SELECT WORKORDERNUMBER                AS TASKWORKORDRENUMBER
                               , PARENT                       AS TASKPARENT
                               , NVL(TOTALMATESTCOSTFORWO, 0) AS TOTALMATESTCOSTFORWO_TASK
                               , NVL(TOTALLABESTCOSTFORWO,0)         AS TOTALLABESTCOSTFORWO_TASK
                               , NVL(TOTALMATACTCOSTFORWO,0)         AS TOTALMATACTCOSTFORWO_TASK
                               , NVL(TOTALLABACTCOSTFORWO,0)         AS TOTALLABACTCOSTFORWO_TASK
                               , NVL(TOTALLABACTHOURSFORWO,0)        AS TOTALLABACTHOURSFORWO_TASK
                        FROM   R_PCR_ALLWOSANDTASKSSEPARATELY)TASKINFO
         ON ( WOINFO.WORKORDERNUMBER = TASKINFO.TASKPARENT )
WHERE  WORKORDERNUMBER = '2826059'; 

1 Ответ

6 голосов
/ 02 марта 2012

Вам необходимо применить NVL после того, как результаты будут возвращены LEFT-соединением.

Попробуйте:

SELECT  WOINFO.*
                , TASKWORKORDRENUMBER
                , TASKPARENT
                , NVL(TOTALMATESTCOSTFORWO_TASK,0) AS TOTALMATESTCOSTFORWO_TASK
                , NVL(TOTALLABESTCOSTFORWO_TASK,0) AS TOTALLABESTCOSTFORWO_TASK
                , NVL(TOTALMATACTCOSTFORWO_TASK,0) AS TOTALMATACTCOSTFORWO_TASK
                , NVL(TOTALLABACTCOSTFORWO_TASK,0) AS TOTALLABACTCOSTFORWO_TASK
                , NVL(TOTALLABACTHOURSFORWO_TASK,0) AS TOTALLABACTHOURSFORWO_TASK
FROM   R_PCR_ALLWOSANDTASKSSEPARATELY WOINFO
       LEFT OUTER JOIN (SELECT WORKORDERNUMBER                AS TASKWORKORDRENUMBER
                               , PARENT                       AS TASKPARENT
                               , TOTALMATESTCOSTFORWO_TASK
                               , TOTALLABESTCOSTFORWO_TASK
                               , TOTALMATACTCOSTFORWO_TASK
                               , TOTALLABACTCOSTFORWO_TASK
                               , TOTALLABACTHOURSFORWO_TASK
                        FROM   R_PCR_ALLWOSANDTASKSSEPARATELY) TASKINFO
         ON ( WOINFO.WORKORDERNUMBER = TASKINFO.TASKPARENT )
WHERE  WORKORDERNUMBER = '2826059'; 
...