SELECT mit Bedinung aus zweiter Tabelle performant gestalten

Getting started ... Alles für einen gelungenen Start.
22 Beiträge • Seite 1 von 2 (current) Nächste
22 Beiträge Seite 1 von 2 (current) Nächste

SELECT mit Bedinung aus zweiter Tabelle performant gestalten

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
Guten Morgen,

als ABAP-Frischling steh ich vor folgendem Problem:

aus der Tabelle knbk sollen nur die Zeilen mit den Kundennummern selektiert werden, die in der Tabelle kna1 KEINEN Löschvermerk haben. Kann ich das ganze performant in einem Select abbilden? Ich hab bis jetzt nur total unperformante Lösungen mit Loop und delete hinbekommen.

Exzellent wäre eine dynamische Lösung. Der bisherige Select sieht so aus:

Code: Alles auswählen.

  IF ( i_iban IS INITIAL OR NOT p_bupa IS INITIAL )
    AND p_up IS INITIAL.
    SELECT * FROM (i_table) AS b
      UP TO p_maxl ROWS
      INTO TABLE <table>
      FOR ALL ENTRIES IN gt_cntry
      WHERE (l_where)
        AND NOT EXISTS ( SELECT iban FROM tiban
                          WHERE (l_wher2) ).
(i_table) wäre in dem Fall "knbk".

Ich kann das ganze aber auch in nen CASE einbauen und prüfen, ob es sich um lfbk / knbk / .... handelt, falls es nötig ist die Tabellen statisch anzugeben. Hab scho versucht n join zu basteln aber der lief dann minutenlang bis ich abgebrochen hab. Da die Tabellen ~ 2 Mio Einträge beinhalten, ist eine performante Lösung wichtig.

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


Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Unit605 (Expert / 975 / 37 / 93 ) »
Einen simplen "INNER JOIN" wuerde ich anwenden.

<F1-Hilfe zu "INNER JOIN" ansehen.

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Alexander D. (Expert / 682 / 30 / 84 ) »
guten Morgen,

ich hätte da zwei Ansätze anzubieten:

1) über einen Join, wie du es schon probiert hast. Ist jetzt allerdings erstmal schnell gecodet und nicht dynamisch

Code: Alles auswählen.

TYPES: BEGIN OF t_knbk,
  kunnr LIKE knbk-kunnr,
  banks LIKE knbk-banks,
  bankl LIKE knbk-bankl,
  bankn LIKE knbk-bankn,
  END OF t_knbk.

DATA: gt_knbk TYPE STANDARD TABLE OF t_knbk,
      wa_knbk LIKE LINE OF gt_knbk.

"der Join liest auch Kunden ohne Bankverbindung. Falls nicht geünscht --> Inner Join anwenden
SELECT kna1~kunnr knbk~banks knbk~bankl knbk~bankn
  FROM kna1 LEFT OUTER JOIN knbk ON kna1~kunnr = knbk~kunnr
  APPENDING TABLE gt_knbk
  WHERE kna1~loevm = ''.
Wie hast du deinen Join aufgebaut? Wir haben in den Tabellen bei weiten nicht so viele Datensätze, ich kann also das Laufzeitverhalten bei 2 Mio. Datensätzen nicht testen.

2) die nicht zum Löschen vorgemerkten Kunden in eine separate interne Tabelle GT_KNA1 lesen, anschliessend KNBK lesen mit FOR ALL ENTRIES IN GT_KNA1. Der Join müsste aber eigentlich performanter sein

Folgende Benutzer bedankten sich beim Autor Alexander D. für den Beitrag:
Leonidas

schöne Grüße
Alexander

ECC 6.0 EHP 7

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
[Zwecks Übersichtlichkeit zurückgesetzt]
Zuletzt geändert von Leonidas am 03.05.2012 13:55, insgesamt 1-mal geändert.

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Alexander D. (Expert / 682 / 30 / 84 ) »
Leonidas hat geschrieben:Mal angenommen, ich möchte vorerst nur alle Kundennummern (kunnr) aus knbk selektieren, die in kna1 keinen Löschvermerk haben: wie fasse ich das im Join in eine Bedinung?

Code: Alles auswählen.

SELECT knbk~kunnr 
  FROM kna1 JOIN knbk ON kna1~kunnr = knbk~kunnr
  APPENDING TABLE gt_knbk
  WHERE kna1~loevm = ''
  GROUP BY knbk~kunnr.
schöne Grüße
Alexander

ECC 6.0 EHP 7

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Was spricht gegen

select {feldliste} from knbk
where kunnr in ( select kunnr from kna1
where loevm eq space ).

?

Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
Leonidas

Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
Danke ralf.wenzel, das geht natürlich! Ich stand davor auf dem Schlauch weil ich eigentlich alle aus knbk wollte, unabhängig davon, ob sie in kna1 stehn oder nicht. Dabei ist mir entgangen, dass natürliche alle, die in knbk stehn auch in kna1 sind und dadurch funktioniert diese einfache Lösung für meinen Fall! Das Coding hatte ich auskommentiert sogar noch drin stehn :)

Wie bekomme ich das nun aber dynamisch hin?

Code: Alles auswählen.

  CASE p_table.               " Festlegen der Hilfsvariablen
    WHEN 'KNBK'.
      lw_htab = 'kna1'.
      lw_hval = 'kunnr'.
    WHEN 'LFBK'.
      lw_htab = 'lfa1'.
      lw_hval = 'liefnr'.
    WHEN OTHERS.
  ENDCASE.

* And now... SELECT
  IF ( i_iban IS INITIAL OR NOT p_bupa IS INITIAL )
    AND p_up IS INITIAL.
    SELECT * FROM (i_table) AS b
      UP TO p_maxl ROWS
      INTO TABLE <table>
      FOR ALL ENTRIES IN gt_cntry
      WHERE lw_hval IN ( SELECT lw_hval
                           FROM (lw_htab)         
                          WHERE LOEVM = '' )      
      AND   (l_where)
      AND   NOT EXISTS ( SELECT iban
                           FROM tiban
                          WHERE (l_wher2) ).
So funktionierts nicht, bekomm ich nen dump.

"Eine Open SQL-Klausel wurde dynamisch angegeben. Der darin auftretende
Feldname "LW_HVAL" kommt in keiner der Datenbanktabellen aus der
FROM-Klausel vor."

Gibts hierfür ne Möglichkeit oder muss ich den Select kopieren?

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Literale immer in Großbuchstaben angeben. Und das Lieferantenfeld heißt LIFNR, nicht LIEFNR.

Aus Neugierde: Zeig mal deinen SELECT.

Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
Leonidas

Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
Stimmt ;)

Trotzdem noch der Dump:

Eine Open SQL-Klausel wurde dynamisch angegeben. Der darin auftretende
Feldname "LW_HVAL" kommt in keiner der Datenbanktabellen aus der
FROM-Klausel vor.

Code: Alles auswählen.

    SELECT * FROM (i_table) AS b
      UP TO p_maxl ROWS
      INTO TABLE <table>
      FOR ALL ENTRIES IN gt_cntry
      WHERE lw_hval IN ( SELECT lw_hval          
                           FROM (lw_htab)         
                          WHERE LOEVM = '' )      
      AND   (l_where)
      AND   NOT EXISTS ( SELECT iban
                           FROM tiban
                          WHERE (l_wher2) ).

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Alexander D. (Expert / 682 / 30 / 84 ) »
Leonidas hat geschrieben: Trotzdem noch der Dump:
LW_HVAL ist eine Variable für die dynamische Selektion. In dem ersten Unterselect ist es nicht geklammert und wird als Feldname interpretiert. Daher auch die Fehlermeldung "Feldname "LW_HVAL" kommt in keiner der Datenbanktabellen aus der FROM-Klausel vor"
schöne Grüße
Alexander

ECC 6.0 EHP 7

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Ah. Der Fall ist klar. Du kannst nicht einfach link in der WHERE-Bedingung einen Feldnamen angeben. Das wird interpretiert als Feld der Tabelle. Es gelten die Regeln für dyn. WHERE-Bedingungen.

Sprich: Wenn du den statischen (ersten) Teil deiner WHERE-Bedingung (mitsamt der Subquery, also dem KNA1-SELECT) in den dynamischen (zweiten) Teil deiner WHERE-Bedingung aufnimmst, sollte es gehen.

Wie performant das dann noch ist (die WHERE-Bedingung geht ja nach dem dyn. Teil ja noch weiter), vermag ich aber nicht vorauszusagen.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »
Alexander D. hat geschrieben:LW_HVAL ist eine Variable für die dynamische Selektion. In dem ersten Unterselect ist es nicht geklammert und wird als Feldname interpretiert. Daher auch die Fehlermeldung "Feldname "LW_HVAL" kommt in keiner der Datenbanktabellen aus der FROM-Klausel vor"
Die Fehlermeldung bezieht sich auf das erste Auftreten (zwischen WHERE und IN im ersten / äußeren SELECT).
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
Ja schon, aber wie kann ich das dort dynamisch zuweisen? Es muss ja entweder KUNNR oder LIFNR sein. Habs mit FIELD-SYMBOLS versucht aber nicht hinbekommen.

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von ralf.wenzel (Top Expert / 3924 / 200 / 280 ) »

Code: Alles auswählen.

concatenate lw_hval 'IN ( select' lw_hval 'FROM' lw_htab 'WHERE LOEVM eq space )' 
into l_where
separated by space.
Die Inhalte der Feldnamen werden dann zur Laufzeit eingesetzt und fertig ist die Laube.

Alternativ ginge auch:

Code: Alles auswählen.

concatenate lw_hval 'IN ( select' lw_hval 'FROM (lw_htab) WHERE LOEVM eq space )' 
into l_where
separated by space.
Das sollte ergebnisgleich sein, unterstreicht aber optisch, dass der Tabellenname dyn. mitgegeben wird.

Den Rest dann zusammenbauen mit

Code: Alles auswählen.

concatenate l_where {bish. dyn. WHERE-Clause} into l_where by space.
So, jetzt MUSS es funktionieren, der Akku vom iPad ist leer ;)
Zuletzt geändert von ralf.wenzel am 03.05.2012 15:22, insgesamt 1-mal geändert.
Bild
Ralf Wenzel Heuristika SAP-Development
25 Jahre SAP-Entwickler • 20 Jahre Freiberufler
PublikationenUngarische NotationXing

Re: SELECT mit Bedinung aus zweiter Tabelle performant gesta

Beitrag von Leonidas (ForumUser / 11 / 3 / 0 ) »
Ich hab auch schonmal das ganze Teil in nen String gepackt, dann hat er aber gemeckert, dass da kein "select" drinstehn darf. Ich versuchs mal mit deiner Lösung, danke schon mal.

Das Selbe:

Das laufende ABAP-Programm wollte eine Open SQL-Anweisung ausführen,
die eine WHERE-, ON- oder HAVING-Bedingung mit einem dynamischen Anteil
enthält.
Der Teil der WHERE-, ON- bzw. HAVING-Bedingung, der zur Laufzeit in
einem Feld bzw. einer internen Tabelle angegeben wurde, enthält den
unzulässigen Wert "SELECT".
Zuletzt geändert von Leonidas am 03.05.2012 15:30, insgesamt 1-mal geändert.

Vergleichbare Themen

2
Antw.
4567
Views
WD zweiter ALV fälschlicherweise im ersten ALV dargestellt
von Thanatos82 » 07.11.2012 15:02 • Verfasst in Web Application Server
2
Antw.
4375
Views
Mengeneinheit in zweiter Sprache pflegen?
von vhoffe » 10.10.2006 13:37 • Verfasst in Basis
2
Antw.
6097
Views
Arbeitspläne performant lesen
von Bugfix13 » 04.02.2016 14:04 • Verfasst in ABAP® Core
1
Antw.
1389
Views
Zeilenindex in Standardtabelle performant finden
von DeathAndPain » 09.10.2018 15:16 • Verfasst in ABAP® für Anfänger
2
Antw.
1504
Views
DB-Abfragen/ITab-Handling möglichst performant umsetzen
von 205er » 27.03.2013 12:59 • Verfasst in ABAP® für Anfänger

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.

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
Gestern von Bright4.5 1 / 511
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2146
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8742