2013-05-02 4 views
0

У меня есть следующий запрос.Oracle: Смешение NVL с Outer Join

Единственный «левый» стол - один с псевдонимом «o».

Я хочу указать следующее. Как я могу сделать? Должен ли я использовать конструкцию WITH temp?

AND ( NVL (domb.DOMB_CONTO_CORRENTE, ' ') != o.campo43 
OR NVL (abi.abi_descrizione, ' ') != o.campo41 
OR NVL (cab.cab_descrizione, ' ') != o.campo42) 

Вот полный текст заявления:

SELECT /*+ parallel(o 64) */ 
     o.stato, COUNT (1) 
    FROM CONF_RAGGRUPPAMENTI_FORN rgf, 
     CRD_RID_REL_DOMICILIAZIONE crrd, 
     CRD_DOMICILIAZIONI domb, 
     uff_abi abi, 
     uff_abi_cab cab, 
     CONTO_CLIENTE_T809 o, 
     eni_flussi_hub c, 
     eni_monitor mon 
    WHERE  1 = 1 
     --RGF - OUT 
     AND rgf.RGF_CODICE_RAGGRUPPAMENTO(+) = o.campo1 
     --Join tra OUT e la ENI_FLUSSI_HUB 
     AND o.id_messaggio = c.flh_id_messaggio(+) 
     AND o.d_pubblicazione = c.flh_data_elaborazione(+) 
     --Join tra ENI_FLUSSI_HUB e ENI_MONITOR 
     AND c.FLH_ID_MESSAGGIO = MON.MON_ID_MESSAGGIO(+) 
     AND c.FLH_TIPO_PROCESSO_COD = MON.MON_COD_TP_PROCESSO(+) 
     AND c.flh_flag_ann(+) = 'N' 
     AND mon_flag_ann(+) = 'N' 
     --Join da RGF a DOMB 
     AND rgf.UITR_IDENT_TIPI_RAGGR_ID(+) = 'MP' 
     AND rgf.RGF_RAGGRUPPAMENTO_FORN_ID = crrd.RGF_RAGGRUPPAMENTO_FORN_ID(+) 
     AND crrd.DOMB_DOMICILIAZIONE_ID = domb.DOMB_DOMICILIAZIONE_ID(+) 
     AND CRRD.CRRD_RID_REL_DOM_ID = crrd.crrd_storico_id 
     AND CRRD.CRRD_FLAG_ANN (+) = 'N' 
     AND domb.domb_flag_ann (+) = 'N' 
     AND rgf.rgf_flag_ann(+) = 'N' 
     --Join tra domb e abi e cab 
     AND DOMB.ABI_ID = abi.ABI_ID(+) 
     AND DOMB.CAB_ID = cab.CAB_ID(+) 
     --Filtro sulle date 
     AND o.d_pubblicazione BETWEEN TO_DATE ('06-apr-2013') 
            AND TO_DATE ('14-apr-2013') 
     --Solo i flussi che producono variazioni 
     AND ( NVL (domb.DOMB_CONTO_CORRENTE, ' ') != o.campo43 
       OR NVL (abi.abi_descrizione, ' ') != o.campo41 
       OR NVL (cab.cab_descrizione, ' ') != o.campo42) 
GROUP BY o.stato 
+0

Какая версия оракула? –

+1

@ Gik25: Я бы рекомендовал прекратить использование 20-летнего (и нестандартного) синтаксиса для 'LEFT JOIN'. В дополнение к улучшенной читаемости вы сможете писать более гибкие условия естественным образом ... – a1ex07

+0

Это оракул 11g – Revious

ответ

2

Если можно, я бы рекомендовал переписывать запрос в современном синтаксисе ANSI. Это делает запрос не только более удобочитаемым, но и проще применять предикаты на дополнительной таблице в ясной форме. Я переписал «старые» запросы Oracle, и обычно это быстрое вырезание и вставка, чтобы переместить условия соединения из предложения WHERE в пункт FROM ... JOIN ... ON ....

Затем любые предикаты, которые применяются к необязательной таблице, перечислены под условием OUTER JOIN, а не под кодом WHERE. Например (в очень грубый пример):

SELECT 
    mt.col1, 
    mt.col2, 
    ot.col3 
    -- other columns ... 
FROM main_table mt 
LEFT OUTER JOIN optional_table ot ON mt.col1 = ot.col1 
    AND ot.col2 = 'N' 
    AND NVL (ot.some_column, 'x') != mt.col5 
-- Now the where for the result set and main table 
WHERE 
AND mt.col4 BETWEEN TO_DATE ('06-apr-2013') AND TO_DATE ('14-apr-2013') 
-- Other conditions on the total result set. 

Я нашел самый простой способ применить условия для дополнительного стола без исключения строк из конечного набора.

1

Вам не нужно использовать + на NVL, потому что вы устанавливаете внешнее соединение уже на идентификаторе domp, abi и кабины.

Я согласен с остальными, что использование оператора JOIN делает более читаемым SQL Selects.

У вас возникли проблемы с запросом?

+0

Спасибо. Вы уверены в своем первом предложении? – Revious

+1

На самом деле да, потому что я предполагаю, что идентификаторы уже передают ссылку, поскольку они действуют как первичный/внешний ключ. В основном вы можете легко это проверить. Когда вы их не используете, вы можете увидеть, что у вас просто слишком много уникальных строк. Затем вы дополнительно уменьшаете набор результатов с помощью дополнительного места. Это намного яснее, если вы используете другой синтаксис.В 'LEFT JOIN ON' я всегда только соединяю ключи, а затем в разделе' WHERE' добавляю дополнительные критерии выбора. Я очень уверен (в предположении, что я только что упомянул) – hol