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
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.
- Interview mit Björn Schulz (Software-Heroes.com) - 3. September 2024
- Daten aus ALV ermitteln - 3. September 2024
- So lange es den SAPGUI noch gibt… - 27. Juni 2024
Danke für die Erläuterungen und das praktische Beispiel für Sub-Queries!
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
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