Tabellenviews und Joins in ABAP
Dieser Beitrag ist Teil des Kurses ABAP Grundlagen.
In diesem Artikel erläutere ich die Funktionsweise der Joins in ABAP. Dabei gehe ich, um Sie an das Thema heranzuführen, zunächst auf Views an. In einem View kann man Tabellen miteinander verknüpfen (Join) und einzelne Tabellenfelder in den View übernehmen.
Dieser View kann in einem Programm zum Lesen von Daten verwendet werden, zum Beispiel mit einem SELECT-Statement. Dabei werden die Daten im View selbst nicht gespeichert, sondern von den darunterliegenden Tabellen angezeigt.
Views
Betrachten wir das folgende Beispiel.
Die Kunden aus der Tabelle ZCUSTOMER
MANDT | CUSTOMID | VORNAME | NACHNAME |
001 | 00000001 | Philipp | Reis |
001 | 00000002 | Konrad | Zuse |
001 | 00000003 | Graham | Bell |
und die Adressen aus ZADDRESS
MANDT | ADDRESSID | CUSTOMID | ORT | PLZ |
001 | 00000001 | 00000001 | Gelnhausen | 63571 |
001 | 00000002 | 00000001 | Friedrichsdorf | 61381 |
001 | 00000003 | 00000001 | Frankfurt am Main | 60313 |
001 | 00000004 | 00000001 | Kassel | 34117 |
001 | 00000005 | 00000001 | Heidelberg | 69115 |
001 | 00000006 | 00000002 | Hoyerswerda | 02977 |
001 | 00000007 | 00000002 | Berlin | 10707 |
werden in einem View verknüpft.
MANDT | CUSTOMID | ADDRESSID | VORNAME | NACHNAME | ORT | PLZ |
001 | 00000001 | 00000001 | Philipp | Reis | Gelnhausen | 63571 |
001 | 00000001 | 00000002 | Philipp | Reis | Friedrichsdorf | 61381 |
001 | 00000001 | 00000003 | Philipp | Reis | Frankfurt am Main | 60313 |
001 | 00000001 | 00000004 | Philipp | Reis | Kassel | 34117 |
001 | 00000001 | 00000005 | Philipp | Reis | Heidelberg | 69115 |
001 | 00000002 | 00000006 | Konrad | Zuse | Hoyerswerda | 02977 |
001 | 00000002 | 00000007 | Konrad | Zuse | Berlin | 10707 |
Es existieren vier verschiedene View-Typen, die sich hinsichtlich der Art der Realisierung und in den möglichen Zugriffsarten unterscheiden. Datenbank-Views werden durch einen View auf der Datenbank realisiert. Mit Projektions-Views können Felder aus einer Tabelle ausgeblendet werden. Help-Views können als Selektionsmethode in Suchhilfen verwendet werden. Mit Pflege-View können die auf mehrere Tabellen verteilten Daten gemeinsam gepflegt werden. Dabei realisieren Datenbank-Views einen Inner Join. Die anderen View-Typen realisieren einen Outer Join. Bei Datenbank-Views können die Join-Bedingungen über Gleichheitsbeziehungen zwischen beliebigen Basisfeldern formuliert werden. Bei den anderen View-Typen müssen Sie aus bestehenden Fremdschlüsseln übernommen werden. Tabellen können also nur dann in einem Pflege-View oder Help-View zusammengefasst werden, wenn sie über Fremdschlüssel miteinander verbunden sind.
Inner Join
Ein Inner Join liefert die Sätze des Kreuzprodukts, zu denen in allen am View beteiligten Tabellen ein Eintrag existiert. Man erhält also nur solche Sätze, zu denen in allen am View beteiligten Tabellen ein Eintrag vorhanden ist.
Betrachten wir das folgende Beispiel. Wir haben eine Tabelle mit Kunden.
MANDT | CUSTOMID | VORNAME | NACHNAME |
001 | 1 | Philipp | Reis |
001 | 2 | Konrad | Zuse |
001 | 3 | Graham | Bell |
Und eine mit Adressen.
MANDT | ADDRESSID | CUSTOMID | ORT | PLZ |
001 | 1 | 1 | Gelnhausen | 63571 |
001 | 2 | 2 | Hoyerswerda | 02977 |
001 | 3 | 2 | Berlin | 10707 |
Für den dritten Kunden existiert keine Adresse. Der Inner Join liefert folgende Ergebnisse.
MANDT | CUSTOMID | ADDRESSID | VORNAME | NACHNAME | ORT | PLZ |
001 | 1 | 1 | Philipp | Reis | Gelnhausen | 63571 |
001 | 2 | 2 | Konrad | Zuse | Hoyerswerda | 02977 |
001 | 2 | 3 | Konrad | Zuse | Berlin | 10707 |
Inner Join liefert die Sätze des Kreuzprodukts, zu denen in allen am View beteiligten Tabellen ein Eintrag existiert. Daher kommen nur die Kunden 1 und 2 im Ergebnis vor.
Outer Join
Ein Outer Join selektiert auch solche Sätze, zu denen in einigen der am View beteiligten Tabellen kein Eintrag existiert. Bei den gleichen Ausgangsdaten wie im Inner Join Beispiel liefert der Outer Join folgende Ergebnisse.
MANDT | CUSTOMID | ADDRESSID | VORNAME | NACHNAME | ORT | PLZ |
001 | 1 | 1 | Philipp | Reis | Gelnhausen | 63571 |
001 | 2 | 2 | Konrad | Zuse | Hoyerswerda | 02977 |
001 | 2 | 3 | Konrad | Zuse | Berlin | 10707 |
001 | 3 | Grahem | Bell |
Beim Outer Join kommen alle Kunden aus der Kundentabelle vor, auch wenn sie keine Adresse haben. Falls Adressen für den Kunden vorhanden sind, werden sie zum Kunden angezeigt.
Um einen View zu definieren gehen Sie wie folgt vor:
- Legen Sie die Basistabellen an
- Setzen Sie diese mit Join-Bedingungen in Verbindung
- Wählen Sie die Felder, die in den View übernommen werden
- Definieren Sie die Selektionsbedingungen
- Optional können Sie noch die technischen Einstellungen setzen
Die Basistabellen ZCUSTOMER
und ZADDRESS
sehen wie folgt aus. Die ZCUSTOMER
Tabelle trägt die Kundeninformationen.
In ZADDRESS
sind die Adressen hinterlegt.
Diese sind über einen Fremdschlüssel mit den Kunden verknüpft.
Nun wollen wir einen View, also eine Sicht auf die Kunden- und Adressdaten, definieren, damit wir einfach Kunden- und deren Adressdaten lösen können. Die Views werden wie die Datenbanktabellen in der Transaktion SE11
(ABAP Dictionary) angelegt.
Wählen Sie einfach View aus und geben Sie einen Namen ein, zum Beispiel ZVCUAD
. Mit der Anlegen Taste wird der View angelegt. Nun fragt das System, welche Art von View angelegt werden soll.
Da wir nur Daten lesen und nicht pflegen wollen, wählen wir einen Datenbank-View aus.
Als Nächstes tragen wir die Basistabellen ZCUSTOMER
und ZADDRESS
ein.
In Reiter Viewfelder werden die Felder definiert. Klicken Sie dazu auf den Button Tabellenfelder. Nun erscheint ein Pop-up mit Basistabellen.
Mit einem Doppelklick auf die ZCUSTOMER
Tabelle kommen Sie in die Feldauswahl.
Wählen Sie alle Felder aus und bestätigen Sie mit der Übernehmen Taste. Damit werden die Felder der Basistabelle ZCUSTOMER
in den View übernommen. Wiederholen Sie die Prozedur für ZADDRESS
Tabelle. Nun haben wir alle Felder der beiden Tabellen im View. Der besseren Übersicht halber habe ich die Schlüsselfelder über Ausschneiden und Einfügen an den Anfang gestellt.
Wenn wir aber den View zu aktivieren versuchen, kommt die Fehlermeldung, dass Feldname CUSTOMID
nicht eindeutig ist. Die Felder Kunden-ID und Mandant kommen in beiden Tabellen vor. Um eine Abgrenzung zu ermöglichen, verwenden wir AD_
als Präfix. Damit ist angedeutet, dass diese Felder aus der Adressentabelle kommen.
Nun lässt sich der View aktivieren. Mit der Taste Inhalt
können wir uns die Daten anzeigen lassen.
Was wir sehen, ist ein Kreuzprodukt aus den Inhalten der zwei Tabellen. Der View kombiniert jeden Eintrag aus der Kundentabelle mit jedem Eintrag in der Adressentabelle.
Das entspricht jedoch nicht dem erwarteten Ergebnis.
MANDT | CUSTOMID | ADDRESSID | VORNAME | NACHNAME | ORT | PLZ |
001 | 00000001 | 00000001 | Philipp | Reis | Gelnhausen | 63571 |
001 | 00000001 | 00000002 | Philipp | Reis | Friedrichsdorf | 61381 |
001 | 00000001 | 00000003 | Philipp | Reis | Frankfurt am Main | 60313 |
001 | 00000001 | 00000004 | Philipp | Reis | Kassel | 34117 |
001 | 00000001 | 00000005 | Philipp | Reis | Heidelberg | 69115 |
001 | 00000002 | 00000006 | Konrad | Zuse | Hoyerswerda | 02977 |
001 | 00000002 | 00000007 | Konrad | Zuse | Berlin | 10707 |
Daher definieren wir nun die Verknüpfung (Join) zwischen den Tabellen in Reiter Tabellen/Joinbedingungen. Dort können Sie die Verknüpfung manuell definieren, falls keine Fremdschlüssel vorhanden sind. Da wir einen Fremdschlüsselverbindung von ZADDRESS
zu ZCUSTOMER
definiert haben, kann das System die Verknüpfungen auch selbst produzieren. Mit der Taste Beziehungen können Sie die von ZCUSTOMER
abhängige Tabellen auswählen.
Nachdem Sie die Tabelle ZADDRESS
ausgewählt und mit der Taste Übernehmen bestätigt haben, wird die Verknüpfung (Join) in den Joinbedingungen angezeigt.
Nachdem Sie den View aktivieren, werden nur die Daten angezeigt, die sich tatsächlich verknüpfen lassen. Es werde also alle Daten aus ZCUSTOMER
, die auch Einträge in ZADDRESS
haben, werden angezeigt (Inner Join).
Dieses Resultat entspricht eher dem erwarteten Ergebnis.
MANDT | CUSTOMID | ADDRESSID | VORNAME | NACHNAME | ORT | PLZ |
001 | 00000001 | 00000001 | Philipp | Reis | Gelnhausen | 63571 |
001 | 00000001 | 00000002 | Philipp | Reis | Friedrichsdorf | 61381 |
001 | 00000001 | 00000003 | Philipp | Reis | Frankfurt am Main | 60313 |
001 | 00000001 | 00000004 | Philipp | Reis | Kassel | 34117 |
001 | 00000001 | 00000005 | Philipp | Reis | Heidelberg | 69115 |
001 | 00000002 | 00000006 | Konrad | Zuse | Hoyerswerda | 02977 |
001 | 00000002 | 00000007 | Konrad | Zuse | Berlin | 10707 |
Nun entfernen wir noch die semantisch überflüssigen Felder AD_MANDT
und AD_CUSTOMID
.
Im Reiter Selektionsbedingungen können Sie für einen View Bedingungen für die Datenselektion angeben. Diese werden als Filter für die aufzubauende Sicht verwendet. Restriktionen können für die Inhalte der View-Felder angegeben werden. Es können dann nur solche Datensätze über den View selektiert werden, die dieses Restriktionen genügen. In einer Selektionsbedingung wird der Inhalt eines Feldes durch einen Operator mit einer Konstanten verglichen. Darüber hinaus können mehrere Selektionsbedingungen über AND
und OR
verknüpft werden. Eine Selektionsbedingung kann auch über ein nicht im View enthaltenes Feld formuliert werden.
Das Ergebnis würden dann wie folgt aussehen.
Nun können Sie mit dem View wie mit einer Tabelle arbeiten, zum Beispiel Datensätze über ein SELECT-Statement lesen.
DATA lt_view TYPE TABLE OF zvcuad.
SELECT * FROM zvcuad INTO TABLE lt_view.
Datensätze werden in eine interne Tabelle gelesen und stehen für Weiterverarbeitung zur Verfügung.
Joins in ABAP
Anstatt den View im ABAP Dictionary anzulegen können wir ihn auch direkt in ABAP implementieren. Dabei wird direkt mit der Datenbank kommuniziert und die SAP-Pufferung wird umgangen.
Betrachten wir das folgende Beispiel für einen Inner Join.
Inner Join
DATA lt_view TYPE TABLE OF zvcuad.
SELECT cust~mandt cust~customid cust~vorname cust~name
adr~addressid adr~ort adr~plz
INTO CORRESPONDING FIELDS OF TABLE lt_view
FROM ( zcustomer AS cust INNER JOIN zaddress AS adr
ON cust~customid = adr~customid ).
Bei der internen Tabelle lt_view
übernehme ich den bereits vorhandenen View. Bei einer rein ABAP-basierten Implementierung kann die Tabelle in ABAP angelegt werden.
Hinter dem SELECT
werden die Felder aufgelistet, die von den Datenbanktabellen gelesen werden sollen. Da diese aus verschiedenen Tabellen stammen, müssen wir definieren aus welchen. so bedeutet zum Beispiel cust~customid
, dass aus der Tabelle cust
die Spalte customid
zu lesen ist. Die Tilde ~ ist ein Spaltenselektor.
Dabei ist cust
ein Alias für die zcustomer
Tabelle. So müssen wir nicht immer den ganzen Namen tippen. In den Klammern nach dem FROM
werden zuerst die am Join beteiligten Tabellen definiert. Für jede der angegebenen Datenbanktabellen kann mit AS
ein alternativer Tabellenname (Alias) angegeben werden. Mit INNER JOIN
realisieren wir einen Inner Join. Mit einem LEFT OUTER JOIN
wird ein Outer Join implementiert. Anschließend definieren wir die Verknüpfung eingeleitet mit ON
. Der aktuelle Mandant wird automatisch verwendet und muss in der Verknüpfung nicht angegeben werden.
Das Ergebnis eines Inner Joins sieht wie gewohnt aus.
Outer Join
DATA lt_view TYPE TABLE OF zvcuad.
SELECT cust~mandt cust~customid cust~vorname cust~name
adr~addressid adr~ort adr~plz
INTO CORRESPONDING FIELDS OF TABLE lt_view
FROM ( zcustomer AS cust LEFT OUTER JOIN zaddress AS adr
ON cust~customid = adr~customid ).
Bei einem Outer Join werden auch Felder ausgegeben, die nur in einer Tabelle vorhanden sind.
Diese ABAP Tricks machen Ihr Leben leichter!
- In meinem Newsletter gebe ich eine Menge Tipps und Kniffe rund um ABAP.
- Die Mini-Tutorials unterstützen Sie dabei, Software in ABAP effizienter zu entwickeln.
- Praktische Anleitungen ermöglichen Ihnen schnelle Erfolge bei der Optimierung Ihrer Arbeit.
- Bei der Anmeldung zu meinem Newsletter erhalten Sie das Buch „ABAP Tipps und Tricks“ als Willkommensgeschenk.
Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.
Hinterlasse einen Kommentar
An der Diskussion beteiligen?Hinterlasse uns deinen Kommentar!