减少左连接的复杂性

时间:2017-12-26 23:00:51

标签: sql oracle

嗨我实际上正在使用oracle 11g中的查询,我的查询非常大。有没有办法减少我的左连接?

我不知道如何减少它们,实际上,我认为我使用了代码的每一部分,你能给我一些如何减少代码的建议吗?

SELECT FOLIO_EXP,
       FOLIO,
       DOC,
       REFERENCIA,
       TARJETA,
       CUENTA,
       NOMBRE,
       IMPORTE,
       IMP_REC,
       IMP_REPRE,
       IMP_QUEB,
       FECHA_PAGO,
       MCC,
       COMERCIO,
       PCC,
       FECHA_COM,
       ADQUIRENTE,
       ESTADO,
       "TIPO DE FRAUDE",
       F_FRAUDE,
       F_RECLAMO,
       F_REEMBOLSO,
       DICAMINO
FROM
  (SELECT E.FOLIO_EXP,
          A.FOLIO,
          'D' AS DOC,
          A.REFERENCIA,
          A.TARJETA,
          A.ACCT_NUM AS CUENTA,
          B.NOMBRE_TH AS NOMBRE,
          TO_CHAR(A.MONTO,'999,999.99') IMPORTE,
          D.IMP_REC,
          F.IMP_REPRE,
          DECODE((A.MONTO -D.IMP_REC),NULL,A.MONTO,(A.MONTO -D.IMP_REC)) AS IMP_QUEB,
          D.FECHA_PAGO,
          A.SIC_CDE AS MCC,
          A.COMERCIO,
          C.PCC,
          C.FECHA_COM,
          C.ADQUIRENTE,
          C.ESTADO,
          'INTERNET' AS "TIPO DE FRAUDE",
          A.FECHA_TRANS AS F_FRAUDE,
          A.FECHA_RECLAMO AS F_RECLAMO,
          A.FECHA_BONIFICACION AS F_REEMBOLSO,
          A.USUARIO AS DICAMINO
   FROM OPPF.T00EMISOR A

   LEFT JOIN
     (SELECT A.FECHA,
             A.TARJETA,
             C.PCC,
             C.FECHA_COM,
             C.ADQUIRENTE,
             C.ESTADO
      FROM
        (SELECT TARJETA,
                MAX(FECHA_INFO) FECHA
         FROM OPPF.T00_PCC
         GROUP BY TARJETA) A
      LEFT JOIN
        (SELECT FECHA_INFO,
                TARJETA,
                PCC,
                FECHA_COM,
                ADQUIRENTE,
                ESTADO
         FROM OPPF.T00_PCC)C ON(A.TARJETA = C.TARJETA
                                AND A.FECHA = C.FECHA_INFO)) C ON(TO_CHAR(C.TARJETA) = TO_CHAR(A.TARJETA))

   LEFT JOIN
     (SELECT MAX(SE_REVISO) SE_REVISO,
             NOMBRE_TH,
             TARJETA
      FROM OPPF.T00CASOSRESUELTOS
      GROUP BY TARJETA,
               NOMBRE_TH) B ON(SUBSTR(A.TARJETA,1,16) = SUBSTR(B.TARJETA,1,16)
                               AND A.FECHA_BONIFICACION = B.SE_REVISO)
   LEFT JOIN
     (SELECT MAX(FECHA_PAGO) FECHA_PAGO,
             TARJETA,
             REFERENCIA,
             COUNT(REFERENCIA) N,
             SUM(MONTO_LIQ) AS IMP_REC--, FECHA_TRXS

      FROM OPPF.T00_CC_RECUP
      GROUP BY TARJETA,
               REFERENCIA,
               FECHA_TRXS) D ON(TO_CHAR(D.TARJETA) = TO_CHAR(A.TARJETA)
                                AND D.REFERENCIA = A.REFERENCIA)
   LEFT JOIN
     (SELECT TARJETA,
             COUNT(TARJETA) TRANS,
             COUNT(REFERENCIA) NR,
             REFERENCIA,
             SUM(IMPORTE) IMP_REPRE
      FROM OPPF.T00_REPRESENTACIONES
      GROUP BY TARJETA,
               REFERENCIA) F ON(A.TARJETA = F.TARJETA
                                AND LPAD(TO_CHAR(A.REFERENCIA),23,'0') = LPAD(TO_CHAR(F.REFERENCIA),23,'0'))
   LEFT JOIN
     (SELECT MIN(FOLIO) FOLIO_EXP,
             TARJETA,
             FECHA_BONIFICACION
      FROM OPPF.T00EMISOR --WHERE FECHA_BONIFICACION BETWEEN '02/09/2015' AND '31/12/2015'

      GROUP BY FECHA_BONIFICACION,
               TARJETA
      ORDER BY FECHA_BONIFICACION,
               TARJETA,
               FOLIO_EXP) E ON(E.TARJETA = A.TARJETA
                               AND E.FECHA_BONIFICACION = A.FECHA_BONIFICACION)
   WHERE A.ENTRY_MODE IN ('   ',
                          '1',
                          '01',
                          '001',
                          '0',
                          '00',
                          '012',
                          '010',
                          '12',
                          '10',
                          '11',
                          '011'))
WHERE F_REEMBOLSO = '04/07/2017'

ORDER BY FOLIO,
         REFERENCIA

是否建议使用索引并将其放在sp中?主要问题是如何减少左连接部分。

由于

1 个答案:

答案 0 :(得分:1)

作为初级(非高级)方法,我建议您:

  1. 将每个子查询取出为分离的 VIEW (虽然他们没有任何参数)。

  2. 或者 - 不确定这对您是否有用 - 重新排序查询并为 WITH 子句中的每个子查询声明别名:

    WITH a AS 
    (SELECT ... FROM...),
    b AS 
    (SELECT ... FROM...),
    c AS 
    (SELECT ... FROM...)
    SELECT ... 
    FROM a 
    LEFT JOIN b ... 
    LEFT JOIN c
    

    https://oracle-base.com/articles/misc/with-clause

  3. 或者,考虑使用客户端语言编写相同的查询逻辑。如此巨大的查询通常会成为一场噩梦。