Selects bzw. Inner Joins über mehrere DB-Tabellen

Getting started ... Alles für einen gelungenen Start.
6 Beiträge • Seite 1 von 1
6 Beiträge Seite 1 von 1

Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von L0w-RiDer (Expert / 535 / 83 / 2 ) »
Hallo zusammen,

ich müsste mir Daten zusammenselektieren aus 2 DB-Tabellen. Diese sind aber nicht direkt miteinander verbunden und ich müsste erst über 2 andere DB-Tabelle gehen. Somit habe ich es wie folgt gelöst (siehe Code). Ich habe versucht die ersten 2 DB-Tabellen zu joinen um ein bisschen Platz zu sparen. Bei den anderen habe ich mir das passende Feld gesucht und gehe damit in der anderen DB-Tabelle suche. Ich bin mit meiner Lösung selbst nicht so zufrieden und wollte fragen, wie man sowas eleganter lösen könnte, hat da jemand einen guten Vorschlag??

Das Problem war folgendes :

Wie könnte man sowas 'schön' lösen??

Vielen Dank
Zuletzt geändert von L0w-RiDer am 05.02.2020 16:15, insgesamt 2-mal geändert.

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von Tron (Top Expert / 1327 / 35 / 332 ) »
Moin.
Ein guter Trick bei joins besteht darin, den Quickviewer (SQVI) im ersten Ansatz zu benutzen und nur alle wirklich beteiligten Tabellen/Felder zu selektieren. Der View V_equi hat ja nun viel zu viele Felder, die Du gar nicht brauchst. So etwas geht unheimlich auf die Perfomance.
Also:
Man verwendet SQVI, joined die Tabellen einzeln und
wenn man zufrieden ist, wechselt man in das Coding, was generiert wurde und kopiert den nun performanteren Join in sein eigenes Programm. Cest ca.
Vielleicht auch ein guter Moment mal CDS-Views zu testen.

gruß Jens
<:: XING-Gruppe Tricktresor::>
Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen –
Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen.

Re: Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Ansonsten spricht aber auch nichts dagegen, mehrere Tabellen in einen Join zu packen. Was Tron sagt, ist sicherlich richtig, aber ich bin bei meinen Betrachtungen trotzdem mal von den von Dir verwendeten Tabellen/Views ausgegangen. Die Abhängigkeiten habe ich wie folgt herausgezogen (wäre gut gewesen, wenn das schon im Originalpost gestanden hätte):

v_equi-tplnr --> iflot (unique)
iflot-objnr --> ihpa (non-unique)
ihpa-parnr(10) --> knvv (non-unique)


Sind also eine Menge Kreuzprodukte möglich aufgrund zweier uneindeutig angebundener Tabellen, aber das ist ja nicht Gegenstand der Frage.

Dann kann ich die ihpa mit in den Ausgangs-SELECT packen, indem ich das wie folgt formuliere:

Code: Alles auswählen.

  SELECT v_eq~zz_maschnum v_eq~typbz v_eq~zz_prodlinie v_eq~zz_prodtyp
         v_eq~zz_baureihe v_eq~zz_baugroesse v_eq~eqktx v_eq~equnr
         v_eq~tplnr v_eq~baujj v_eq~stort ifo~objnr ihpa~parnr
    from v_equi as v_eq 
    JOIN iflot as ifo on ifo~tplnr = v_eq~tplnr
    JOIN ihpa on ihpa~objnr = ifo~objnr
      INTO CORRESPONDING FIELDS OF TABLE gt_collect
        WHERE v_eq~equnr in so_sapnr
        and   v_eq~tplnr in so_saptp.
Die knvv hätte ich auch gerne mit reingenommen, aber das wird wohl nicht gehen, da Du in der WHERE-Bedingung auf parnr(10) vergleichst, und ich denke nicht, dass solch Teilfeldvergleich in einem Join möglich ist.

Ansonsten habe ich aber noch eine Reihe von Anmerkungen zu Deinem Code:
  • Bei seinem ersten Auftreten ist das Feldsymbol <fs_collect> gar nicht ASSIGNED. Da fehlt irgendwas, vermutlich ein LOOP über die gt_collect.
  • Die Aliases, die Du in Deinem Select gesetzt hast, halte ich für kontraproduktiv. Wenn Du die Zeichen abziehst, die Du für die Definition des Alias selbst brauchst, dann sparst Du bei v_equi nur wenige Zeichen. Bei iflot legst Du sogar drauf; das wäre ohne Alias insgesamt kürzer! Der Preis, den Du aber in jedem Fall zahlst, ist, dass Dein ganzer Select schlechter lesbar ist, weil man bei jedem Feld eben immer überlegen muss, aus welcher Datenbanktabelle es kommt, weil anstelle des Tabellennamens halt nur ein Aliasname davor steht. In meinem obenstehenden Beispiel habe ich noch die ihpa mit drangejoint und dafür keinen Alias verwendet, und das liest sich prima, finde ich.

    Aliases benutze ich nur dann, wenn ich dieselbe Tabelle mehrfach in unterschiedlichen Rollen in ein- und demselben Select benötige. Dann geht es nicht anders, und dann kann man den Aliasnamen nutzen, um deutlich zu machen, in welcher Rolle man sie gerade verwendet. (Ein gutes Beispiel für eine Tabelle aus dem HCM, bei der man sowas brauchen kann, ist die HRP1001.)
  • Die Klammer in Deinem Select ist unnötig. Das System braucht sie nicht, und für den Leser gliederst Du besser durch Zeilenumbrüche.
  • Deine ganzen FOR ALL ENTRIES sind gefährlich, weil Du vorher nicht prüfst, ob die interne Tabelle leer ist. In diesem Fall würde der FOR ALL ENTRIES Dir ganz böse um die Ohren fliegen, weil der Select dann komplett ohne WHERE-Bedingung ausgeführt wird (also die gesamte Zieltabelle findet)!
  • Der Block

    Code: Alles auswählen.

          READ TABLE gt_ihpa INTO gs_ihpa with KEY objnr = <fs_collect>-objnr.
          if sy-subrc = 0.
            <fs_collect>-parnr = gs_ihpa-parnr.
          ENDIF.
    gefällt mir nicht, denn er ist oldschool. Du kannst den ganzen Block durch eine einzige Zeile ersetzen:

    Code: Alles auswählen.

    <fs_collect>-parnr = VALUE #( gt_ihpa [ objnr = <fs_collect>-objnr ]-parnr OPTIONAL ).
    Der einzige funktionale Unterschied zu Deinem Code ist, dass <fs_collect>-parnr in diesem Falle auf Initialwert gesetzt werden würde, wenn es die entsprechende Zeile in der gt_ihpa gar nicht gibt. Bei Deinem Code dürfte das aber keinen Nachteil darstellen. Zugleich kannst Du Dir damit die Definition der ganzen Ballast-Workareavariable gs_ihpa (also den entsprechenden DATA-Befehl) komplett sparen.

    Wenn Du die neue Schreibweise als schlecht lesbar empfindest, dann liegt das daran, dass Du sie nicht gewohnt bist. Am Anfang ging mir das auch so. Man sollte sich gegen Neuerungen aber nicht sperren und in veralteter Denke verhärten. Wenn Du mit der neuen Schreibweise rumspielst und sie Dir antrainierst, dann wirst Du sehr bald merken, dass sie sogar besser lesbar ist als der alte Kram und wirst sie nicht mehr missen wollen. Sich bei Tabellenzugriffen die blöden Workareafelder sparen zu können, ist ein Riesenvorteil!

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
L0w-RiDer


Re: Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von jocoder (Specialist / 343 / 3 / 102 ) »
Mit CDS Views kann das tatsächlich ziemlich elegant gelöst werden.

OpenSQL

Code: Alles auswählen.

 SELECT v_eq~zz_maschnum v_eq~typbz v_eq~zz_prodlinie v_eq~zz_prodtyp
         v_eq~zz_baureihe v_eq~zz_baugroesse v_eq~eqktx v_eq~equnr
         v_eq~tplnr v_eq~baujj v_eq~stort ifo~objnr
    from ( v_equi as v_eq INNER JOIN iflot as ifo on v_eq~tplnr = ifo~tplnr )
      INTO CORRESPONDING FIELDS OF TABLE gt_collect
        WHERE v_eq~equnr in so_sapnr
        and   v_eq~tplnr in so_saptp

select objnr parnr
    from ihpa
      INTO TABLE gt_ihpa
        for ALL ENTRIES IN gt_collect
        WHERE objnr = gt_collect-objnr.

    loop at gt_collect ASSIGNING <fs_collect>.
      READ TABLE gt_ihpa INTO gs_ihpa with KEY objnr = <fs_collect>-objnr.
      if sy-subrc = 0.
        <fs_collect>-parnr = gs_ihpa-parnr.
      ENDIF.
    ENDLOOP.
CDS View:

Code: Alles auswählen.

define view zmaintenance_partner as select from v_equi as v_eq inner join to iflot as ifo on v_eq~tplnr = ifo~tplnr
association to ihpa as pa on pa.objnr = ifo.objnr {

  v_eq.zz_maschnum,
  v_eq.typbz,
  v_eq.zz_prodlinie,
  v_eq.zz_prodtyp,
  v_eq.zz_baureihe,
  v_eq.zz_baugroesse,
  v_eq.eqktx,
  v_eq.equnr,
  v_eq.tplnr,
  v_eq.baujj,
  v_eq.stort,
  ifo.objnr,
  cast( pa.parnr as abap.char(10) ) as partner_no

}
Auf dem View zmaintenance_partner kannst du dann einen weiteren View aufbauen, die den folgenden Part übernimmt:

Code: Alles auswählen.

 SELECT kunnr vkgrp
   from knvv
   INTO TABLE gt_knvv
   FOR ALL ENTRIES IN gt_collect
   WHERE kunnr = gt_collect-parnr(10).

loop at gt_collect ASSIGNING <fs_collect>.
  READ TABLE gt_knvv INTO gs_knvv with KEY kunnr = <fs_collect>-parnr.
  if sy-subrc = 0.
    <fs_collect>-kunnr = gs_knvv-kunnr.
    <fs_collect>-vkgrp = gs_knvv-vkgrp.
  else.
    if <fs_collect>-parnr <> ''.
      delete gt_collect.
    endif.
  ENDIF.
ENDLOOP.
CDS View

Code: Alles auswählen.

define view zmaintenance_sales_group as select from zmaintenance_partner as pa inner join to knvv as sg on sg.kunnr = pa.parnr {
  pa.zz_maschnum,
  pa.typbz,
  pa.zz_prodlinie,
  pa.zz_prodtyp,
  pa.zz_baureihe,
  pa.zz_baugroesse,
  pa.eqktx,
  pa.equnr,
  pa.tplnr,
  pa.baujj,
  pa.stort,
  pa.objnr,
  sg.kunnr,
  sg.vkgrp
}
Auf ABAP Seite kannst du dann ein einziger SELECT-Statement auf den CDS View zmaintenance_sales_group implementieren. Voraussetzung dazu ist SAP NetWeaver 7.51 und Eclipse.

Re: Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von L0w-RiDer (Expert / 535 / 83 / 2 ) »
Okay, vielen Dank für die Tipps.

<fs_collect>-parnr = VALUE #( gt_ihpa [ objnr = <fs_collect>-objnr ]-parnr OPTIONAL ). --> Ich habe jetzt mal versucht das zu verwenden, allerdings werden die eckigen Klammern immer rot angezeigt und ich bekomme die Meldung "Der Typ PARNR ist keine Struktur".

Re: Selects bzw. Inner Joins über mehrere DB-Tabellen

Beitrag von DeathAndPain (Top Expert / 1952 / 259 / 413 ) »
Bist Du noch auf einem SAP-Release unter 7.40?

Ansonsten kleiner Flüchtigkeitsfehler auf meiner Seite: zwischen gt_ihpa und [ darf kein Leerzeichen sein!

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
L0w-RiDer


Seite 1 von 1

Vergleichbare Themen

3
Antw.
1337
Views
Tabellen Joins
von ek53 » 07.12.2016 10:19 • Verfasst in ABAP® für Anfänger
4
Antw.
2641
Views
form für die selects
von BabsiCSC » 23.06.2008 17:21 • Verfasst in ABAP® Core
6
Antw.
1096
Views
Mehrer Selects in eine Tabelle bringen
von burggartenkind » 25.07.2019 13:44 • Verfasst in ABAP® für Anfänger
13
Antw.
1315
Views
SQL JOINS
von ABAPlerv » 18.05.2022 14:11 • Verfasst in ABAP® für Anfänger
19
Antw.
5684
Views
Joins
von Neu_Im_SAP » 25.07.2011 13:15 • Verfasst in ABAP® für Anfänger

Über diesen Beitrag


Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Aktuelle Forenbeiträge

Regex in where
vor 5 Stunden von edwin 7 / 163
Daten an Tabelle binden
vor 18 Stunden von Bright4.5 3 / 1487

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

Regex in where
vor 5 Stunden von edwin 7 / 163
Daten an Tabelle binden
vor 18 Stunden von Bright4.5 3 / 1487

Unbeantwortete Forenbeiträge

aRFC im OO-Kontext
vor 5 Wochen von ralf.wenzel 1 / 3261
Hilfe bei SWEC/SWE2
September 2024 von retsch 1 / 9822