Subquerys
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).