Inner-join

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • apauber
    Junior Member
    • jun
    • 17

    #1

    Inner-join

    Hola a todos, tengo que reemplazar un inner-join a 5 tablas porque esta teniendo un problema de performans. Me pidieron que desarme el Inner-Join en en 5 selects distintos.
    Mi objetivo es tener el mismo resultado que da el inner-join con mis selects separados.
    Voy a copiar el INNER-JOIN y mis 5 select con el proceso de los datos. Lo que les pido es si me pueden ayudar un poco porque no esta funcionando correctamente.
    Si pueden marcarme los erroros y mostrarme como deberia ser me harian un gran favor.
    INNER-JOIN:

    * select a~vbeln a~posnr a~bstdk a~zlsch a~bstkd a~bstkd_e a~ihrez_e a~pltyp b~fkdat a~fplnr
    * b~fpltr b~faksp b~afdat b~netpr b~kzwi1 b~kzwi3 b~kzwi4 b~kzwi5
    * c~matnr c~matkl c~netwr c~waerk c~aufnr c~bankn c~banks c~kdmat
    * e~folio e~neto e~iva e~total
    * into corresponding fields of table wa
    * from vbkd as a
    * inner join fplt as b on b~fplnr = a~fplnr
    * inner join zclsd03_tventa as e on e~vbeln = a~vbeln
    * and e~posnr = a~posnr
    * and e~fplnr = b~fplnr
    * and e~fpltr = b~fpltr
    * and e~zlsch = a~zlsch
    * inner join vbap as c on c~vbeln = a~vbeln
    * and c~posnr = a~posnr
    * inner join vbak as f on f~vbeln = c~vbeln
    *
    * where a~vbeln in s_vbeln
    * and a~bstkd in s_bstkd
    * and a~zlsch in r_zlsch
    * and b~faksp in r_faksp
    * and b~fkdat in r_fkdat
    * and b~fksaf ne c_fksaf
    * and a~pltyp in r_pltyp
    * and f~faksk ne '02'.

    Y ASÍ LO REEMPLACÉ:

    Código:
     SELECT vbeln posnr bstdk  zlsch bstkd bstkd_e ihrez_e pltyp fplnr
        INTO TABLE t_vbkd
        FROM vbkd
        WHERE vbeln IN s_vbeln
        AND   bstkd IN s_bstkd
        AND   zlsch IN r_zlsch
        AND   pltyp IN r_pltyp.
    
      IF sy-subrc = 0.
        SELECT fplnr fkdat fpltr faksp afdat netpr kzwi1 kzwi3 kzwi4 kzwi5
          INTO TABLE t_fplt
          FROM fplt
          FOR ALL ENTRIES IN t_vbkd
          WHERE faksp IN r_faksp
          AND   fkdat IN r_fkdat
          AND   fksaf NE c_fksaf
          AND   fplnr =  t_vbkd-fplnr.
    
        IF sy-subrc = 0.
          SORT t_vbkd BY fplnr.
          SORT t_fplt BY fplnr.
          LOOP AT t_vbkd INTO e_vbkd.
            LOOP AT t_fplt INTO e_fplt WHERE fplnr = e_vbkd-fplnr.
              IF sy-subrc = 0.
                CLEAR e_vbkd_flplt-vbeln.
                e_vbkd_flplt-vbeln   = e_vbkd-vbeln.
                e_vbkd_flplt-posnr   = e_vbkd-posnr.
                e_vbkd_flplt-bstdk   = e_vbkd-bstdk.
                e_vbkd_flplt-zlsch   = e_vbkd-zlsch.
                e_vbkd_flplt-bstkd   = e_vbkd-bstkd.
                e_vbkd_flplt-bstkd_e = e_vbkd-bstkd_e.
                e_vbkd_flplt-ihrez_e = e_vbkd-ihrez_e.
                e_vbkd_flplt-pltyp   = e_vbkd-pltyp.
                e_vbkd_flplt-fplnr   = e_vbkd-fplnr.
                e_vbkd_flplt-fkdat   = e_fplt-fkdat.
                e_vbkd_flplt-fpltr   = e_fplt-fpltr.
                e_vbkd_flplt-faksp   = e_fplt-faksp.
                e_vbkd_flplt-afdat   = e_fplt-afdat.
                e_vbkd_flplt-netpr   = e_fplt-netpr.
                e_vbkd_flplt-kzwi1   = e_fplt-kzwi1.
                e_vbkd_flplt-kzwi3   = e_fplt-kzwi3.
                e_vbkd_flplt-kzwi4   = e_fplt-kzwi4.
                e_vbkd_flplt-kzwi5   = e_fplt-kzwi5.
                APPEND e_vbkd_flplt TO  t_vbkd_flplt.
              ENDIF.
            ENDLOOP.
          ENDLOOP.
    
          IF t_vbkd_flplt[] IS NOT INITIAL.
            SELECT folio neto iva total vbeln posnr fplnr fpltr zlsch
              INTO TABLE t_zclsd03_tventa
              FROM zclsd03_tventa
              FOR ALL ENTRIES IN t_vbkd_flplt
              WHERE vbeln = t_vbkd_flplt-vbeln
              AND   posnr = t_vbkd_flplt-posnr
              AND   fplnr = t_vbkd_flplt-fplnr
              AND   fpltr = t_vbkd_flplt-fpltr
              AND   zlsch = t_vbkd_flplt-zlsch.
    
            SELECT vbeln posnr matnr matkl netwr waerk aufnr bankn banks kdmat
              INTO TABLE t_vbap
              FROM vbap
              FOR ALL ENTRIES IN t_vbkd_flplt
              WHERE vbeln = t_vbkd_flplt-vbeln
              AND   posnr = t_vbkd_flplt-posnr.
    
            SELECT vbeln
              INTO TABLE t_vbak
              FROM vbak
              FOR ALL ENTRIES IN  t_vbkd_flplt
              WHERE vbeln =  t_vbkd_flplt-vbeln
              AND   faksk NE '02'.
    
            IF sy-subrc = 0.
              SORT: t_vbak BY vbeln,
                    t_vbkd_flplt BY vbeln,
                    t_zclsd03_tventa BY vbeln posnr fplnr fpltr zlsch,
                    t_vbap BY vbeln posnr.
              LOOP AT  t_vbkd_flplt INTO  e_vbkd_flplt.
                CLEAR wa.
                READ TABLE t_vbak INTO e_vbak WITH KEY vbeln = e_vbkd_flplt-vbeln.
                IF sy-subrc = 0.
                  READ TABLE t_zclsd03_tventa INTO e_zclsd03_tventa WITH KEY  vbeln = e_vbkd_flplt-vbeln
                                                                              posnr = e_vbkd_flplt-posnr
                                                                              fplnr = e_vbkd_flplt-fplnr
                                                                              fpltr = e_vbkd_flplt-fpltr
                                                                              zlsch = e_vbkd_flplt-zlsch.
                  READ TABLE t_vbap INTO e_vbap WITH KEY vbeln = e_vbkd_flplt-vbeln
                                                         posnr = e_vbkd_flplt-posnr.
    
                  wa-vbeln   = e_vbkd_flplt-vbeln.
                  wa-posnr   = e_vbkd_flplt-posnr.
                  wa-bstdk   = e_vbkd_flplt-bstdk.
                  wa-zlsch   = e_vbkd_flplt-zlsch.
                  wa-bstkd   = e_vbkd_flplt-bstkd.
                  wa-bstkd_e = e_vbkd_flplt-bstkd_e.
                  wa-ihrez_e = e_vbkd_flplt-ihrez_e.
                  wa-pltyp   = e_vbkd_flplt-pltyp.
                  wa-fplnr   = e_vbkd_flplt-fplnr.
    *               wa-fkdat   = e_vbkd_flplt-fkdat.
                  wa-fpltr   = e_vbkd_flplt-fpltr.
                  wa-faksp   = e_vbkd_flplt-faksp.
                  wa-afdat   = e_vbkd_flplt-afdat.
                  wa-netpr   = e_vbkd_flplt-netpr.
                  wa-kzwi1   = e_vbkd_flplt-kzwi1.
                  wa-kzwi3   = e_vbkd_flplt-kzwi3.
                  wa-kzwi4   = e_vbkd_flplt-kzwi4.
                  wa-kzwi5   = e_vbkd_flplt-kzwi5.
                  wa-matnr   = e_vbap-matnr.
                  wa-matkl   = e_vbap-matkl.
    *               wa-netwr   = e_vbap-netwr.
                  wa-waerk   = e_vbap-waerk.
                  wa-aufnr   = e_vbap-aufnr.
                  wa-bankn   = e_vbap-bankn.
                  wa-banks   = e_vbap-banks.
                  wa-kdmat   = e_vbap-kdmat.
                  wa-folio   = e_zclsd03_tventa-folio.
                  wa-neto    = e_zclsd03_tventa-neto.
                  wa-iva     = e_zclsd03_tventa-iva.
                  wa-total   = e_zclsd03_tventa-total.
                ENDIF.
              ENDLOOP.
            ENDIF.
          ENDIF.
        ENDIF.
      ENDIF.
    Espero puedan ayudarme porque no se en que me estoy equivocando, muchisimas gracias .
    Saludos !!
  • Atlas
    Senior Member
    • ago
    • 107

    #2
    Hola.

    Así a simple vista esta bien, por lo menos el planteamiento, pero ten en cuenta dos cosas que tal vez estén afectando.

    1 - el for all entries, intrinsecamente implica un delete duplicates. Así que para que no te borre los duplicados, en la tabla interna tienes que recoger todos los campos clave de la tabla a la que haces el select ( aunque luego no los utilices )

    2 - estas haciendo read a las tablas internas, ten en cuenta que esto es correcto si la correspondencia entre la primera tabla y el resto es 1 <> 1, si es 1 <> n deberías hacer un loop where.

    Espero que te sirva de ayuda

    Comentario

    • apauber
      Junior Member
      • jun
      • 17

      #3
      Muchas Gracias

      La verdad no sabia lo del for all entries así que ahora me fijo eso y si no estoy recuperando los campos claves voy a empezar a hacerlo. Con respecto a lo que me decis del Read eso creo que esta bien porque a las tablas que les hago read accedo unicamente por la clave.
      Muchas gracias por la ayuda !!!
      De todas formas si alguien mas encuentra algun error porfavor diganme porque así como esta la logica, no me recupera lo mismo que el inner joing.

      Comentario

      • apauber
        Junior Member
        • jun
        • 17

        #4
        Eso Funciona

        Me fije lo de los accesos a las tablas con el for all entries y estoy recuperando todos los campos claves así que eso no es lo que me esta funcionando mal.
        Porfavor si me pueden seguir ayudando voy a estar muy agradecido.

        Comentario

        • jacmono
          Member
          • jun
          • 48

          #5
          Lo que les pido es si me pueden ayudar un poco porque no esta funcionando correctamente.
          Podrías ser mas especifico? Que diferencias te da el inner join vs el reemplazo que has implementado?

          Así de inicio me parece que se debe validar primero la cantidad de registros de uno vs el otro. Luego, que todos los campos llave que obtiene el inner join los arroje también el reemplazo, y posteriormente, que el resto de los campos correspondan entre ambos procedimientos, obvio con un ordenamiento idéntico de los resultados para facilitar la validación.

          En el innerjoin veo que la tabla "f" (vbak) sólo se usa para validar que exista faksk diferente de '02', sin obtener información de ella. En el reemplazo lo puedes incluir en algún select previo (el primero , por ejemplo) y evitar el acceso sobre la tabla t_vbak, asumiendo que todos los resultados cumplieron con esa regla (faksk ne '02').

          Obvio que la cantidad de registros y por ende el resultado final esta afectado por las relaciones 1-1 / 1-n que pudieran existir entre las distintas tablas que utilizas, así como por los indices declarados en tu b.d.

          Sin duda alguna, el proporcionar mayor detalle facilitara la tarea de quienes te podrían prestar ayuda.

          Saludos.
          Jack of all Trades

          Comentario

          Trabajando...