CDS - Aggregation
Wie können Core Data Services den meisten Mehrwert liefern? Vor allem bei Aggregationen und Code-Pushdown glänzen die Views.
Inhaltsverzeichnis
Artikel-Update: Seit Release 7.57 (S/4 HANA 2022) ist DEFINE VIEW als obsolet gekennzeichnet, stattdessen solltest du DEFINE VIEW ENTITY verwenden. Diese können an einigen Stellen zu den Beispielen abweichen. Mehr Informationen zu den neuen Views findest du in diesem Artikel.
In diesem Aritkel schauen wir uns das Thema Aggregation etwas näher an, die eigentliche Superkraft von Core Data Services. Weiterhin gehen wir auf die Verknüpfung solcher Views mit weiteren Daten ein und was für Auswirkungen es auf die Performance haben kann.
Summe
On-Demand die Summe pro Partner und Material aus der Datenbank lesen? Was früher eine Menge Performance oder Hilfstabellen benötigt hat, geht mit einer HANA Datenbank in Millisekunden. Dazu einmal ein Beispiel View der uns genau so eine Summe berechnet und direkt die Assoziation nutzt:
@AbapCatalog.sqlViewName: 'ZBSCDMOPAMATSUM'
@EndUserText.label: 'Sum for Partner and Material'
define view ZBS_C_DmoPartnerMaterialSum
as select from ZBS_I_DmoPosition
{
key _Invoice.PartnerNumber,
key MaterialNumber,
@Semantics.currencyCode: true
PositionCurrency,
sum ( PositionPrice ) as PriceForPartnerMaterial
}
group by
_Invoice.PartnerNumber,
MaterialNumber,
PositionCurrency
Die Schlüsselfelder in dem View haben wir neu definiert und bilden unseren neuen Schlüssel. Ebenso nutzen wir ein Assoziation um an die Partnernummer im Kopf des Belegs zu kommen. Da wir die Summe bilden, müssen wir im Nachgang noch eine Gruppierung definieren. Im nächsten Schritt definieren wir auch einen View um die Summe pro Partner zu ermitteln:
@AbapCatalog.sqlViewName: 'ZBSCDMOPARSUM'
@EndUserText.label: 'Sum for Partner'
define view ZBS_C_DmoPartnerSum
as select from ZBS_I_DmoPosition
{
key _Invoice.PartnerNumber,
@Semantics.currencyCode: true
PositionCurrency,
sum ( PositionPrice ) as PriceForPartnerMaterial
}
group by
_Invoice.PartnerNumber,
PositionCurrency
Im Grunde fehlt nur das Material-Feld und die Gruppierung wurde angepasst. Im Data-Preview kannst du dir dann das Ergebnis anschauen und erhältst jeweils nur eine Zeile pro vorhandenem Partner:
Berechnete Felder
Das Filtern über ein berechnetes Feld ist nicht in dem View möglich, in dem das Feld erzeugt/berechnet wird. Dazu muss eine weiter View implementiert werden, wo dann die Einschränkung durchgeführt werden kann. Für das Beispiel aus dem letzten Abschnitt haben wir noch einen weiteren View für einen Count abgebildet:
@AbapCatalog.sqlViewName: 'ZBSCDMOPAMATCNT'
@EndUserText.label: 'Count for Partner and Material'
define view ZBS_C_DmoPartnerMaterialCount
as select from ZBS_I_DmoPosition
{
key _Invoice.PartnerNumber,
key MaterialNumber,
count( * ) as NumberOfDocuments
}
group by
_Invoice.PartnerNumber,
MaterialNumber
Diese beiden View führen wir nun zu einem neuen Statistik CDS zusammen, in dem wir Informationen pro Partner und Material erhalten. In diesem Fall interessieren uns aber nur Datensätze mit mehr als 10 Belegen und weniger als 100000 Gesamtsumme.
@AbapCatalog.sqlViewName: 'ZBSCDMOSTATPARMA'
@EndUserText.label: 'Statistic for high performer'
define view ZBS_C_DmoStatisticParMat
as select from ZBS_C_DmoPartnerMaterialSum as Combine
inner join ZBS_C_DmoPartnerMaterialCount as Numbers on Combine.PartnerNumber = Numbers.PartnerNumber
and Combine.MaterialNumber = Numbers.MaterialNumber
{
key Combine.PartnerNumber,
key Combine.MaterialNumber,
Combine.PositionCurrency,
Combine.PriceForPartnerMaterial,
Numbers.NumberOfDocuments
}
where
Numbers.NumberOfDocuments >= 10
and Combine.PriceForPartnerMaterial <= 100000
Die Komplexität des CDS Views nimmt mit jeder weiteren Schicht zu, du solltest dabei aber auch die Performance im Auge behalten, vor allem wenn es noch komplexer wird.
Funktionen
Folgende Aggregationsfunktionen kannst du in Core Data Services verwenden, wobei die ersten Beiden die gebräuchlisten sind:
- SUM - Ermittlung der Summe nach Gruppierung
- COUNT - Ermittlung der Anzahl von Datensätzen
- AVG - Durchschnitt der Werte nach Kombination
- MIN/MAX - Kleinster und größter Wert in der Spalte
Performance
Zusammengesetzte Felder oder berechnete Felder haben ein Problem, eine Filterung auf diesem Feld hat nicht die beste Performance und kann einen Zugriff recht langsam machen, wenn es das einzige Filterkriterium ist. Hintergrund ist, dass die Datenbank im ersten Schritt die Operation über alle Datensätze der Datenbank machen muss, bevor die Einschränkung der Datenmenge stattfinden kann. Bei einem Standardfeld gibt es das Problem nicht, die Datenmenge kann passend von der Datenbank gelesen werden.
Ein gutes Beispiel ist Vor- und Nachname die in einem Feld zusammengeführt werden. Die Selektion per Suchfeld über den vollständigen Namen ist performancetechnische sehr schlecht im Gegensatz zum Filtern über die einzelnen Felder.
Fazit
Die Summe pro Beleg ermitteln oder einfach mal die Anzahl der Belege pro Partner lesen? Kein Problem mit den Aggregations Funktionen für Core Data Services. In alten Reports hat man das im Loop gemacht, auf HANA kannst du das die Datenbank machen lassen.
Quelle:
SAP Dokumentation - Aggregation