ABAP - Schlüsselwortdokumentation →  ABAP - Dictionary →  ABAP CDS im ABAP Dictionary →  ABAP CDS - Datendefinitionen →  ABAP CDS - DDL für Datendefinitionen →  ABAP CDS - DEFINE VIEW →  ABAP CDS - SELECT →  ABAP CDS - SELECT, data_source → 

ABAP CDS - SELECT, JOIN

Syntax

... { [INNER] JOIN }|{ LEFT|RIGHT OUTER [TO ONE|MANY] JOIN }|{ CROSS JOIN }
      data_source [ON cond_expr] ...


Zusatz:

... TO ONE|MANY

Wirkung

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:

Bei geschachtelten Join-Ausdrücken wird die Reihenfolge der Auswertung wie folgt gesteuert:

Hinweise

Beispiel

Die folgende CDS-View hat genau die gleiche Funktionalität wie die klassische Datenbank-View DEMO_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.

@AbapCatalog.sqlViewName: 'DEMO_CDS_JOIN'
@AccessControl.authorizationCheck: #NOT_ALLOWED
define view demo_cds_scarr_spfli(
    id,
    carrier,
    flight,
    departure,
    destination
  )
  as select from
           spfli
      join scarr on
        scarr.carrid = spfli.carrid
    {
      key spfli.carrid,
      key scarr.carrname,
      key spfli.connid,
          spfli.cityfrom,
          spfli.cityto
    }

Beispiel

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

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.