DELETE FROM ... NOT IN...

Getting started ... Alles für einen gelungenen Start.
10 Beiträge • Seite 1 von 1
10 Beiträge Seite 1 von 1

DELETE FROM ... NOT IN...

Beitrag von ChristianHo (ForumUser / 21 / 0 / 0 ) »
Hallo zusammen,
ich habe zwei interne Tabellen, die ich vergleichen möchte und anschließend die Zeilen aus Tab2, die nicht in Tab1 vorhanden sind aus der Tab2 löschen will.

Wie mache ich das am besten?
Zuletzt geändert von ChristianHo am 15.02.2016 11:02, insgesamt 1-mal geändert.
Mit freundlichen Grüßen,
ChristianHo

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: Zwei interne Tabellen vergleichen inkl. Editieren

Beitrag von Martin8703 (ForumUser / 12 / 0 / 0 ) »
Ich denke nicht, dass es einen Mengenlehren-Operator für interne Tabellen gibt, die dir die Schnittmenge aus zwei Tabellen zurückgibt.
Vermutlich wirst du über Tab2 loopen müssen und dann alle Zeilen rauswerfen, die nicht in Tab1 vorkommen.

Hier ein Beispiel mit verschiedenen Tabellentypen für die Vergleichstabelle. Der binary search ist in diesem Beispiel die leicht schnellere Variante für das Nachlesen&Löschen.

Code: Alles auswählen.

DATA: gt_sflight_tab2 TYPE STANDARD TABLE OF sflight WITH KEY carrid connid fldate,
      gt_sflight_a TYPE STANDARD TABLE OF sflight WITH KEY carrid connid fldate,
      gt_sflight_b TYPE SORTED TABLE OF sflight WITH UNIQUE KEY carrid connid fldate,
      gt_sflight_c TYPE HASHED TABLE OF sflight WITH UNIQUE KEY carrid connid fldate,
      gt_sflight_d TYPE STANDARD TABLE OF sflight WITH KEY carrid connid fldate,
      g_start TYPE i,
      g_end TYPE i,
      g_runtime TYPE i.

FIELD-SYMBOLS: <wa_sflight_a> TYPE sflight.

START-OF-SELECTION.

  SELECT * FROM sflight
    INTO TABLE gt_sflight_tab2
    WHERE carrid <> 'AZ'.

  SELECT * FROM sflight
    INTO TABLE gt_sflight_b
    WHERE ( carrid = 'AA'
         OR carrid = 'AZ' ).

  gt_sflight_c[] = gt_sflight_b[].
  gt_sflight_d[] = gt_sflight_b[].

  SORT gt_sflight_d BY carrid connid fldate ASCENDING.

* Nachlesen in sortierter Tabelle
  CLEAR: g_start, g_end, g_runtime.
  gt_sflight_a[] = gt_sflight_tab2[].
  GET RUN TIME FIELD g_start.
  LOOP AT gt_sflight_a ASSIGNING <wa_sflight_a>.
    READ TABLE gt_sflight_b WITH KEY carrid = <wa_sflight_a>-carrid
                                     connid = <wa_sflight_a>-connid
                                     fldate = <wa_sflight_a>-fldate
                            TRANSPORTING NO FIELDS.
    IF sy-subrc <> 0.
      DELETE gt_sflight_a USING KEY loop_key.
    ENDIF.
  ENDLOOP.
  GET RUN TIME FIELD g_end.
  g_runtime = g_end - g_start.
  WRITE: / 'Delete after Read Sorted Table', g_runtime , 'micro seconds'.

* Nachlesen in hashed Tabelle
  CLEAR: g_start, g_end, g_runtime.
  gt_sflight_a[] = gt_sflight_tab2[].
  GET RUN TIME FIELD g_start.
  LOOP AT gt_sflight_a ASSIGNING <wa_sflight_a>.
    READ TABLE gt_sflight_c WITH KEY carrid = <wa_sflight_a>-carrid
                                     connid = <wa_sflight_a>-connid
                                     fldate = <wa_sflight_a>-fldate
                            TRANSPORTING NO FIELDS.
    IF sy-subrc <> 0.
      DELETE gt_sflight_a USING KEY loop_key.
    ENDIF.
  ENDLOOP.
  GET RUN TIME FIELD g_end.
  g_runtime = g_end - g_start.
  WRITE: / 'Delete after Read Hashed Table', g_runtime, 'micro seconds'.

* Nachlesen in standard Tabelle (sortiert, binary search)
  CLEAR: g_start, g_end, g_runtime.
  gt_sflight_a[] = gt_sflight_tab2[].
  GET RUN TIME FIELD g_start.
  LOOP AT gt_sflight_a ASSIGNING <wa_sflight_a>.
    READ TABLE gt_sflight_d WITH KEY carrid = <wa_sflight_a>-carrid
                                     connid = <wa_sflight_a>-connid
                                     fldate = <wa_sflight_a>-fldate
                            TRANSPORTING NO FIELDS
                            BINARY SEARCH.
    IF sy-subrc <> 0.
      DELETE gt_sflight_a USING KEY loop_key.
    ENDIF.
  ENDLOOP.
  GET RUN TIME FIELD g_end.
  g_runtime = g_end - g_start.
  WRITE: / 'Delete after Binary Search Standard Table', g_runtime, 'micro seconds'.
Ab einem AS ABAP 7.40 kannst du statt READ TABLE auch line_exists nehmen (dann geht aktuell aber wohl noch kein binary search).

Edit: Der Code wird bei mir ohne öffnende und schließende eckige Klammer dargestellt als "&#91;&#93;". Gemeint ist [ ]

Re: Zwei interne Tabellen vergleichen inkl. Editieren

Beitrag von ChristianHo (ForumUser / 21 / 0 / 0 ) »
Ich bin jetzt auf die Idee gekommen, das ganze mit einer DELETE-Anweisung zu machen.

Mein Quellcode schaut jetzt so aus:

Code: Alles auswählen.

DELETE  gt_fvmk WHERE bukrs NOT IN gt_fvmkvorher-bukrs
                          AND bdatj not in gt_fvmkvorher-bdatj
                          AND poper not in gt_fvmkvorher-poper
                          AND bwvar not in gt_fvmkvorher-bwvar.
Jetzt kommt die Fehlermeldung: "GT_FVMKVORHER" ist eine Tabelle ohne Kopfzeile und besitzt daher keine Komponente mit Namen "BUKRS".

Weiß jemand was ich falsch gemacht habe?
Mit freundlichen Grüßen,
ChristianHo

Re: DELETE FROM ... NOT IN...

Beitrag von a-dead-trousers (Top Expert / 4282 / 214 / 1141 ) »
Der IN-Operator gilt bei internen Tabellen nur für sog. Range-Tabellen.

Was du machen willst geht nur so:

Code: Alles auswählen.

LOOP AT tabelle1 ASSIGNING <zeile1>.
  READ TABLE tabelle2 TRANSPORTING NO FIELDS WITH KEY ...
  IF sy-subrc EQ 0. "= wenn gefunden
    DELETE tabelle1. "= die aktuelle Zeile löschen
  ENDIF.
ENDLOOP.
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: DELETE FROM ... NOT IN...

Beitrag von Martin8703 (ForumUser / 12 / 0 / 0 ) »
Du könntest höchstens versuchen, die interne Tabelle auf eine ähnliche Art zu befüllen (for all entries). Wenn die Daten für table 2 von der DB stammen.

Für das read table solltest du auf einen performanten Zugriff achten. Beispiele habe ich in meinem Post oben gegeben.

Edit: Du könntest natürlich auch entsprechende Ranges aufbauen und dann damit löschen, aber ob das sinnvoll ist hängt von der Ausprägung deiner Selektionsfelder ab.

Re: DELETE FROM ... NOT IN...

Beitrag von wreichelt (Top Expert / 1031 / 29 / 188 ) »
Hallo,

geht das auch ?

DELETE FROM Tabelle1
WHERE NOT EXISTS(SELECT NULL
FROM FILES f
WHERE f.id = fileid)

??

Re: DELETE FROM ... NOT IN...

Beitrag von Tron (Top Expert / 1327 / 35 / 331 ) »
Moin.
Beispiel Select ... not exist.
http://www.abapforum.com/forum/viewtopi ... 495#p55179

So könnte ich anbieten :

Code: Alles auswählen.

*&---------------------------------------------------------------------*
*& Report  YBC_SUBQUERY_DELETE
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ybc_subquery_delete.

DATA t1 TYPE TABLE OF ztest3.

SELECT * FROM ztest3 AS f INTO TABLE t1
WHERE NOT EXISTS ( SELECT * FROM ztest4 WHERE f1 = f~f1 ).
DELETE ztest3 FROM TABLE t1.
lg Jens
<:: XING-Gruppe Tricktresor::>
Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen –
Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen.

Re: DELETE FROM ... NOT IN...

Beitrag von black_adept (Top Expert / 3946 / 105 / 886 ) »
Hallo ChristianHo,

wenn du auf einem relativ aktuellen SAP-Release rumturnst könntest du auch table comprehensions verwenden.
Ich packe mal ein Beispiel hier rein, welches 2 Tabellen enthält mit 3 Zeilen, die in beiden Tabellen vorkommen.
Ist de facto auch nichts anderes als der von A-D-T vorgeschlagene Loop - aber eben als ein einziger Befehl mit den neuen Sprachelementen. Ich persönlich finde a-d-ts Version deutlich lesbarer - aber es gibt halt auch Leute die die neuen Sprachelemente als das Non-Plus-Ultra ansehen.

Code: Alles auswählen.

REPORT.

types: tt_mara type STANDARD TABLE OF mara with NON-UNIQUE DEFAULT KEY.

SELECT * UP TO 10 ROWS
  INTO TABLE @DATA(lt_mara1)
  FROM mara.
DELETE lt_mara1 FROM 7.

SELECT * UP TO 10 ROWS
  INTO TABLE @DATA(lt_mara2)
  FROM mara.
DELETE lt_mara2 TO 3.

DATA(lt_mara3) = VALUE tt_mara( FOR ls_mara1 IN lt_mara1
                                  FOR ls_mara2 IN lt_mara2 WHERE ( table_line = ls_mara1 )
                                    ( ls_mara1 )
                              ).

BREAK-POINT.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: DELETE FROM ... NOT IN...

Beitrag von a-dead-trousers (Top Expert / 4282 / 214 / 1141 ) »
black_adept hat geschrieben:Ist de facto auch nichts anderes als der von A-D-T vorgeschlagene Loop - aber eben als ein einziger Befehl mit den neuen Sprachelementen.
Ich will jetzt nicht die ganzen Loorbeeren alleine kassieren. Martin8703 hat vor mir schon die gleiche Lösung gepostet nur halt umfangreicher, deswegen ging der Loop etwas unter :wink:
Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.18
Basis: 7.50

Re: DELETE FROM ... NOT IN...

Beitrag von Martin8703 (ForumUser / 12 / 0 / 0 ) »
a-dead-trousers hat geschrieben: Ich will jetzt nicht die ganzen Loorbeeren alleine kassieren. Martin8703 hat vor mir schon die gleiche Lösung gepostet nur halt umfangreicher, deswegen ging der Loop etwas unter :wink:
Das ist sehr löblich :wink:

Ich muss aber durchaus selbstkritisch anmerken, dass ich die Antwort besser einfacher gehalten hätte. Ich habe die Fragestellung aber auch für mich selber genutzt, um nochmal in den umfangreichen sprachlichen Möglichkeiten von ABAP zu wühlen. Das Delete-Statement ist ja (wie so viele ABAP-Statements) je nach Kontext mit vielen möglichen Anwendungsmöglichkeiten versehen.

Seite 1 von 1

Vergleichbare Themen

4
Antw.
3737
Views
NATIV SQL - Delete
von verzweifelt » 05.01.2016 00:20 • Verfasst in ABAP® Core
6
Antw.
9956
Views
DELETE * FROM DBTAB
von Timo7 » 27.10.2006 11:36 • Verfasst in ABAP® Core
2
Antw.
3015
Views
DELETE auf grossen Tabellen
von Ralph » 23.01.2006 15:55 • Verfasst in ABAP® Core
1
Antw.
493
Views
Datenbank Delete mit Subquery
von JohnLocklay » 28.05.2019 14:47 • Verfasst in ABAP® Core
4
Antw.
7041
Views
delete from itab mit where Bedingung
von debianfan » 31.07.2019 14:38 • Verfasst in ABAP® für Anfänger

Aktuelle Forenbeiträge

SELECT CHAR16 in CHAR12-Feld
vor 21 Minuten von rob_abc 4 / 45
alv_grid aktualisieren
vor 4 Stunden von Egzon gelöst 4 / 81

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

SELECT CHAR16 in CHAR12-Feld
vor 21 Minuten von rob_abc 4 / 45
alv_grid aktualisieren
vor 4 Stunden von Egzon gelöst 4 / 81

Unbeantwortete Forenbeiträge

Zwischensumme Adobe Forms
vor 4 Wochen von Lucyalison 1 / 134
Group Items auf einer Filterbar
vor 5 Wochen von Bright4.5 1 / 170