Definiert einen Join zweier Datenquellen einer
CDS-View. Die obige Angabe
ist Teil der Syntax einer Datenquelle data_source
und enthält rekursiv wieder die Syntax einer Datenquelle data_source. Zwei über JOIN verknüpfte Datenquellen bilden einen Join-Ausdruck.
In einem Join-Ausdruck mit INNER und OUTER
muss hinter ON eine Join-Bedingung cond_expr angegeben werden, für deren Angabe spezielle
Regeln gelten. In einem Join-Ausdruck mit CROSS darf keine Join-Bedingung angegeben werden.
Es sind innere, äußere und Cross Joins möglich:
Eine Verknüpfung von zwei Datenquellen mit INNER JOIN oder nur JOIN selektiert alle Einträge der Datenquellen, deren Felder die
ON-Bedingung erfüllen.
Eine Verknüpfung von zwei Datenquellen mit LEFT OUTER JOIN
selektiert alle Einträge der linken Seite. Eine Verknüpfung von zwei Datenquellen mit
RIGHT OUTER JOIN selektiert alle Einträge der rechten Seite. Für
die Einträge, für welche die ON-Bedingung erfüllt ist,
ist der Inhalt der gleiche wie beim inneren Join. Für die Einträge, für welche die ON-Bedingung nicht erfüllt ist, haben die Elemente der rechten bzw. linken Seite den
Null-Wert, der bei Verwendung der CDS-View in Open SQL auf den typabhängigen Initialwert gesetzt wird.
Eine Verknüpfung von zwei Datenquellen mit CROSS JOIN bildet
deren Kreuzprodukt. Es werden alle Einträge der linken Seite mit allen Einträgen der rechten
Seite kombiniert. Die Anzahl der Zeilen der Ergebnismenge ist die Anzahl der Zeilen der linken Seite multipliziert mit der Anzahl der Zeilen der rechten Seite.
Bei geschachtelten Join-Ausdrücken wird die Reihenfolge der Auswertung wie folgt gesteuert:
Bei inneren und äußeren Joins durch die Anordnung der ON-Bedingungen.
Von links nach rechts wird jeder JOIN-Verknüpfung die am nächsten
stehende ON-Bedingungen zugeordnet und dieser Ausdruck implizit geklammert. Die implizite Klammerung kann optional mit runden Klammern (
) verdeutlicht werden.
Cross Joins werden standardmäßig von links nach rechts ausgewertet. Die Priorität der Auswertung kann durch runde Klammern ( ) beeinflusst werden.
Bei der Kombination mehrerer Cross Joins spielt die Reihenfolge der Auswertung keine Rolle. Das
Ergebnis ist immer gleich und die Anzahl der Zeilen ist das Produkt der Zeilenanzahl aller beteiligten Datenquellen.
Bei der Kombination von Cross Joins mit inneren und äußeren Joins kann das Ergebnis von der Reihenfolge der Auswertung bzw. der Klammerung abhängen.
Hinweise
Eine WHERE-Bedingung für eine SELECT-Anweisung mit Joins wirkt auf die durch die Joins gebildete Ergebnismenge.
Ein innerer Join oder ein Cross Join zwischen zwei einzelnen Datenquellen ist kommutativ. Beim Vertauschen der linken und rechten Seite bleibt das Ergebnis gleich.
Eine CDS-View, die einen äußeren Join enthält sollte nicht
gepuffert werden. Wegen der möglichen
Null-Werte in der Ergebnismenge,
kann sich ein Zugriff über Open SQL sich beim Zugriff auf den Puffer unterschiedlich zum direkten Zugriff auf die Datenbank verhalten, da Null-Werte im Puffer in Initialwerte umgesetzt werden.
Um Null-Werte in der Ergebnismenge zu verhindern, kann die Funktion coalesce verwendet werden.
Ein Cross Join wirkt wie ein innerer oder äußerer Join, dessen ON-Bedingung
immer wahr ist. Ein Cross Join mit einer WHERE-Bedingung hat das gleiche
Ergebnis wie ein innerer Join mit einer gleichlautenden ON-Bedingung. Im
Gegensatz zum inneren Join werden beim Cross Join aber erst alle Daten gelesen und dann die Bedingung
ausgewertet, während beim inneren Join nur Daten gemäß der ON-Bedingung gelesen werden.
Ein Cross Join sollte nur mit äußerster Vorsicht verwendet werden. Da keine
ON-Bedingung angegeben werden kann, werden immer alle Daten aller beteiligten Datenquellen gelesen.
Bei großen Datenbeständen kann die Ergebnismenge, deren Zeilenanzahl immer das Produkt aus der Anzahl aller Zeilen beider Datenquellen ist, schnell sehr groß werden.
Ein Cross Join zweier mandantenabhängiger Datenquellen wird auf der Datenbank als innerer
Join ausgeprägt, in dessen ON-Bedingung die Mandantenspalten der linken
und rechten Seite auf Gleichheit überprüft werden. Ist eine Seite mandantenunabhängig wird der Cross Join wie angegeben ausgeprägt.
Bei geschachtelten Join-Ausdrücken wird die Verwendung runder Klammern empfohlen, um die
Lesbarkeit zu verbessern. Bei inneren und äußeren Joins können die runden Klammern
genau dort angegeben werden, wo die durch die ON-Bedingungen vorgegebene implizite Klammerung erfolgt.
Die Anzahl der Join-Ausdrücke einer SELECT-Anweisung einer CDS-View ist in der DDL nicht begrenzt. Es gibt aber eine
ATC-Prüfung, die ab einer bestimmten Anzahl eine Meldung ausgibt.
Beispiel
Die folgende CDS-View hat genau die gleiche Funktionalität wie die klassische
Datenbank-ViewDEMO_SCARR_SPFLI.
Das Programm DEMO_CDS_JOIN greift mit SELECT
auf die View zu. Bei einem Zugriff auf die CDS-Entität DEMO_CDS_SCARR_SPFLI wird anders als beim
Zugriff auf die klassische Datenbank-View DEMO_SCARR_SPFLI aber keine Mandantenspalte zurück gegeben. Die CDS-Datenbank-View DEMO_CDS_JOIN gibt auch die Mandantenspalte zurück.
Die folgende nicht geklammerte Verkettung von Join-Ausdrücken
... from tab1 join tab2
join tab3 on tab2.id = tab3.id
on tab1.id = tab2.id ...
wird implizit wie folgt geklammert:
... from tab1 join ( tab2
join
tab3 on tab2.id = tab3.id ) on tab1.id = tab2.id ...
In der inneren ON-Bedingung darf kein Element von tab1 aufgeführt werden.
Beispiel
Die folgende View enthält einen Cross Join der Tabelle T000 aller
Mandanten eines AS ABAP mit den Einträgen für die Nachrichtenklasse SABAPDEMOS in der
Tabelle T100. Das Programm DEMO_CDS_CROSS_JOIN
greift auf die View zu. Ohne die WHERE-Bedingung wäre die Ergebnismenge sehr groß.
@AbapCatalog.sqlViewName: 'DEMO_CDS_CRSJN' @AccessControl.authorizationCheck: #NOT_REQUIRED
define view demo_cds_cross_join as select from t000
cross join t100 { t000.mandt,
t000.mtext, t100.sprsl,
t100.arbgb, t100.msgnr,
t100.text } where t100.arbgb = 'SABAPDEMOS'
Zusatz
... TO ONE|MANY
Wirkung
Angabe der Kardinalität eines links äußeren Joins. Dieser Zusatz ist hinter
LEFT OUTER aber nicht hinter RIGHT OUTER möglich. Er hat nur auf bestimmten Datenbanksystemen eine Wirkung.
Wenn der Zusatz TO ONE oder TO MANY angegeben
ist, geht eine Datenbank, die den Zusatz unterstützt, davon aus, dass die durch den links äußeren
Join definierte Ergebnismenge dieser Kardinalität entspricht und der SQL Optimizer versucht,
unnötige Joins zu unterdrücken. Wenn die Ergebnismenge nicht der Kardinalität entspricht,
ist das Ergebnis undefiniert und kann von den Angaben in der SELECT-Liste abhängen.
Hinweise
Für mehr Informationen siehe die Dokumentation des aktuellen Datenbanksystems. Beispielsweise unterstützt die
SAP-HANA-Datenbank die
Zusätze TO ONE und TO MANY und deren Beschreibung ist Teil der Dokumentation des
HANA-spezifischen SQL.
Um undefiniertes und plattformabhängiges Verhalten zu vermeiden, darf die Angabe von TO
ONE oder TO MANY nur dann erfolgen, wenn die zu lesenden Daten die Voraussetzungen dafür erfüllen.
Beispiel
Falsche Verwendung von TO ONE in CDS-Views. Die Daten in den Datenbanktabellen
SCARR und SPFLI haben keine Kardinalität
TO ONE sondern TO MANY. Zum Beispiel hängt
auf einer SAP-HANA-Datenbank das Ergebnis von der
SELECT-Liste ab. Wenn dort Spalten der linken und rechten Seite angegeben sind wird keine
Optimierung vorgenommen. Wenn keine Spalten der rechten Seite angegeben sind und bei Verwendung der
Aggregatfunktion COUNT(*)
wird eine Optimierung ausgeführt. Dabei werden nur Daten gelesen, die der vorausgesetzten Kardinalität entsprechen.
@AbapCatalog.sqlViewName: 'DEMOCDSWTO1' define view demo_cds_wrong_to_one_1
as select from
scarr as c
left outer to one join spfli as p on c.carrid = p.carrid
{ c.carrid as carrid, c.carrname as carrname,
p.connid as connid }
@AbapCatalog.sqlViewName: 'DEMOCDSWTO2' define view demo_cds_wrong_to_one_2
as select from
scarr as c
left outer to one join spfli as p on c.carrid = p.carrid
{ c.carrid as carrid, c.carrname as carrname }
@AbapCatalog.sqlViewName: 'DEMOCDSWTO3' define view demo_cds_wrong_to_one_3
as select from
scarr as c
left outer to one join spfli as p on c.carrid = p.carrid
{ count(*) as cnt }
Das Programm DEMO_CDS_WRONG_TO_ONE greift auf die CDS-Views zu und stellt die Ergebnisse dar.