Subquerys

Aus SAP-Wiki
Zur Navigation springenZur Suche springen

Siehe Schlüsselbefehl Select.

Es kann auch innerhalb eines Selects auf die Existenz eines Datensatzes einer anderen Tabelle abgeprüft werden, was manchmal durch einen Inner-Join nicht möglich ist.

Siehe unter den Performancebeispielen von SAP (Transaktion SE80, Menü "Umfeld - Beispiele - Performance-Beispiele").

Subquery mit Select (IN / NOT IN)

Der Subquery, wo man mit IN bzw. NOT IN zu einem Feld in der Where-Bedingung den Query in einer Klammer aufführt, ist recht intuitiv, wenn man das Prinzip und die Syntax einmal verstanden hat.

Hier wird bezüglich der Bestellnuimmer EKKO-EBELN geprüft, ob in der BestellhistorienTabelle EKBE diese Bestellung auch nicht mit der Bewegungsart 161 (WE Retoure) vorliegt.

 SELECT
   ...
  FROM ekko            "Bestellung Kopf
    INNER JOIN ekpo    "Bestellung Position
      ON ekko~ebeln = ekpo~ebeln
    WHERE ekko~bukrs IN ...
       AND ekko~ebeln NOT IN ( SELECT ebeln FROM ekbe WHERE bwart = '161' ) "Ausschluß bestimmter Bewegungsart
   INTO TABLE @DATA(lt_items).

oder in einem anderen Projektbeispiel werden Einträge aus der Tabelle KNVV selektiert, wo nicht bereits Einträge in der Tabelle KNVI vorhanden sind.

SELECT
  kunnr
  FROM knvv
  WHERE kunnr IN @mr_kunnr
    AND vkorg = @mp_vkorg
    and vtweg = @mp_vtweg
    and spart = @mp_spart
    and kunnr not in ( select kunnr from knvi where kunnr = knvv~kunnr
                                                and aland = @mp_aland
                                                and tatyp = @mp_tatyp
                                                and taxkd = @mp_taxkd )
  INTO TABLE @mt_itab.

Subquery mit Exist

In einem Projektbeispiel sollen nur Anlieferungen selektiert werden sollen, die auch mindestens 1 Position haben.

SELECT
 likp~vbeln
 FROM likp
 WHERE ( likp~aedat IN @s_dat
      or likp~erdat in @s_dat )
   AND likp~vbeln IN @s_vbeln
   AND EXISTS ( SELECT * FROM lips
                  WHERE vbeln = likp~vbeln )
   and likp~lifex <> likp~vbeln
   INTO TABLE @lt_itab.

Im Flugdatenmodell werden nur die Tages-Flugverbindungen (SFLIGHT) selektiert, für die auch mindestens eine Flugverbindung (SPFLI) existiert.

SELECT * 
   FROM SFLIGHT AS F 
   INTO SFLIGHT_WA
   WHERE SEATSOCC < F~SEATSMAX
     AND EXISTS ( SELECT * FROM SPFLI
                    WHERE CARRID = F~CARRID
                      AND CONNID = F~CONNID
                      AND CITYFROM = 'FRANKFURT'
                      AND CITYTO = 'NEW YORK' )
     AND FLDATE BETWEEN '19990101' AND '19990331'.
ENDSELECT.


Die Umkehrung der Abfrage mit "NOT EXIST ( ... )" ist ebenfalls möglich.

Eine Zeile von Header-Tabelle und Item-Tabelle selektieren

Hier gibt es eine Aufgabenstellung, wo eine Header-Tabelle selektiert wird und eine Zeile von der Item-Tabelle, aber lediglich die Item-Zeile mit der geringsten POSNR selektiert werden soll.

Mit dem Zusatz von "fields MIN( POSNR )" im Subquery konnte hier auf den minimalen Wert vom Feld POSNR abgeprüft werden.

Insgesamt wäre es auch fast richtig gewesen in einem Inner-Join auf die POSNR = 10 abzufragen. Aber in nicht jedem Beleg ist die Position 10 gefüllt - sie könnte auch gelöscht sein. Daher hier diese etwas aufwendigere Datenbankabfrage, um nicht in zwei Schritten den Header und die Item-Tabelle abfragen zu müssen.

SELECT
 z_head~vbeln,
 ...
 item~posnr,
 item~matnr,
 ...

FROM z_head
inner join z_item as item
  on item~vbeln = z_head~vbeln

WHERE item~posnr = ( SELECT from z_item as it fields MIN( POSNR )
                                        where it~vbeln = /ttg/lo_ret_head~vbeln
                                          AND it~matnr IN @s_matnr
                                          ... )

  AND /ttg/lo_ret_head~vbeln    IN @s_vbeln
  ...

INTO TABLE @ct_itab.

Es kann aber auch anders geschrieben werden, ohne den Zusatz "fields".

WHERE item~posnr = ( SELECT MIN( POSNR ) from /ttg/lo_ret_item as it

Siehe Select Aggregierungsfunktionen (MIN, MAX, AVG, SUM, COUNT).

Web-Links