Ist das gültig? (2)

So. da bin ich im letzten Beitrag Ist das gültig? etwas über das Ziel hinaus geschossen… Ein Merkmal des Tricktresors ist es, dass ich die Beispiele auf das Wesentlich und nur absolut Notwendige reduziere. So bleiben die Tricks einfach und klar. Im letzten Beitrag habe ich jedoch etwas zu viel reduziert und der Trick ist für das Beispiel sogar komplizierter als notwendig.

Klarstellung

Natürlich kann man von einem definierten Eintrag sehr einfach den zuletzt – bzw. aktuell – gültigen Eintrag ermitteln. Ingo hat darauf hin gewiesen, dass die folgende Variante doch deutlich einfacher ist als die von mir vorgestellte:

SELECT * FROM ztt_datum
 UP TO 1 ROWS
 INTO ls_datum
 WHERE gueltig_ab <= p_datum
 ORDER BY gueltig_ab DESCENDING.
ENDSELECT.

Recht hat er.

Eigentlich wollte ich auch auf eine andere etwas komplexere Variante heraus. Nämlich die, bei der es nicht den einen Eintrag gibt, sondern eine unbestimmte Menge von Einträgen. Das könnten zum Beispiel alle gültigen Materialien eines Werkes sein oder Konten eines Buchungskreises sein.

Nächster Versuch

Für das neue Beispiel habe ich die folgende Tabelle erstellt:

ZTT_DATUM2

2016-12-05_10-51-52

Aus dieser Tabelle möchte ich alle zu einem Datum gültigen Gruppen ermitteln. Das funktioniert gut mit dem Befehl DELETE ADJACENT DUPLICATES:

SELECT * FROM ztt_datum2 INTO TABLE @DATA(lt_datum)
 WHERE datab <= @p_datum
 ORDER BY gruppe ASCENDING,
          datab  DESCENDING.

DELETE ADJACENT DUPLICATES FROM lt_datum COMPARING gruppe.

Es spricht nichts dagegen, diese Variante zu verwenden. Aber: Alles, was man mit einem Befehl anstelle von zweien lösen kann, ist irgendwie cooler. Zumal es immer schöner ist, nur die Daten zu lesen, die auch wirklich gebraucht werden.

Sub-query

Aus diesem Grund jetzt die wirklich hilfreiche und sinnvolle Variante mithilfe eines Sub-Queries:

SELECT * FROM ztt_datum2 AS z1 INTO TABLE @DATA(lt_datum)
 WHERE datab <= @p_datum
   AND datab  = ( SELECT MAX( datab ) FROM ztt_datum2
                   WHERE gruppe = z1~gruppe
                     AND datab <= @p_datum ).

Der Clou bei dieser Variante ist, dass man sich in der WHERE-Bedingung der Hauptselektion mit einem Sub-Query auf die jeweilige GRUPPE bezieht und hierfür das höchste Datum ermittelt.

Von der Performance her kann es sein, dass die herkömmliche  Variante sogar schneller ist. Da man diesen Select jedoch wahrscheinlich nur für sehr kleine Datenmengen verwenden wird, dürfte die Geschwindigkeit hier zu vernachlässigen sein.

Enno Wulff
Letzte Artikel von Enno Wulff (Alle anzeigen)

COMMENTS

  • <cite class="fn">abapkadabra</cite>

    Danke für die Erläuterungen und das praktische Beispiel für Sub-Queries!

  • <cite class="fn">cacique</cite>

    Hi Enno,

    zunächst mal vielen Dank für diesen Post. Dennoch hätte ich hier eine Anmerkung / Alternative.
    Zu dem Sub-SELECT: dieser ist an sich ja relativ Performance-intensiv, da für jede Zeile die im äußeren SELECT durchlaufen wird einmal der Sub-SELECT ausgeführt wird.
    Wäre es hier nicht sinnvoller den Sub-SELECT einmalig in eine Interne Tabelle zu lesen und das ganze mit einem FOR ALL ENTRIES IN zu lösen?

    Hier das Coding (ist allerdings von mir ungetestet):
    SELECT gruppe, MAX( datab ) as datab
    INTO TABLE ltab
    FROM ztt_datum2
    WHERE datab <= @p_Datum
    GROUP BY gruppe.

    SELECT *
    INTO TABLE @DATA(lt_datum)
    FROM ztt_datum2 AS z1
    FOR ALL ENTRIES IN ltab
    WHERE gruppe = ltab-gruppe
    AND datab = ltab-datab.

    Korrigier mich bitte, sollte ich falsch liegen, aber nach meinem aktuellem Stand wäre das doch die performantere Lösung und dürfte zum selben Ergebnis führen.

    Gruß,

    Christian

    • <cite class="fn">Enno Wulff</cite>

      Hi Christian, es geht hier nicht in erster Linie um Schnelligkeit.
      Prinzipiell dürftest du jedoch Recht haben.
      Danke für deinen alternativen SELECT!
      Gruß Enno

Comments are closed.