0

我有以下查询。

唯一的“左”表是别名为“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
4

2 回答 2

2

如果可以的话,我建议您用现代 ANSI 语法重写您的查询。这不仅使查询更具可读性,而且更容易以清晰的方式在可选表上应用谓词。WHERE我已经重写了“旧”Oracle 查询,将连接条件从子句移动到子句通常是一种快速剪切和粘贴工作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.

我找到了将条件应用于可选表而不从最终集中排除行的最简单方法。

于 2013-05-02T15:58:34.407 回答
1

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

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

查询有问题吗?

于 2013-05-02T18:56:45.137 回答