Oracle:将NVL与外部联接混合使用

时间:2013-05-02 14:56:04

标签: sql oracle

我有以下问题。

唯一的“左”表是别名为“o”的表。

我想指定以下内容。我能怎么做?我应该使用WITH临时​​构造吗?

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

2 个答案:

答案 0 :(得分: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 :(得分:1)

您不需要在NVL上使用+,因为您已经在domp,abi和cab的ID上建立了外连接。

我同意其他人使用JOIN语句使SQL选择更具可读性。

您对查询有任何疑问吗?