Gruppierung und Aggregationen
Archie Core bietet leistungsstarke Gruppierungs- und Aggregationsfunktionen über seine GraphQL-API. Sie können Datensätze nach Feldwerten gruppieren, Aggregationsfunktionen (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT) berechnen, Gruppen mit HAVING-Bedingungen filtern und Ergebnisse nach aggregierten Werten sortieren.
Abfrageargumente
Abschnitt betitelt „Abfrageargumente“Bei Verwendung von Gruppierung und Aggregationen stehen die folgenden Argumente für jede Listenabfrage zur Verfügung:
| Argument | Typ | Beschreibung |
|---|---|---|
groupBy | [{TableName}GroupBy] | Felder zum Gruppieren der Ergebnisse |
aggregateBy | [{TableName}AggregateInput] | Zu berechnende Aggregationsfunktionen |
having | [{TableName}HavingFilterInput] | Gruppen nach aggregierten Ergebnissen filtern |
aggregateSort | [{TableName}AggregateSortInput] | Ergebnisse nach aggregierten Werten sortieren |
Diese Argumente können mit Standardargumenten wie filter, first, skip und orderBy kombiniert werden.
GroupBy
Abschnitt betitelt „GroupBy“Das Argument groupBy akzeptiert ein Array von Enum-Werten, die die zu gruppierenden Felder darstellen. Enum-Werte folgen dem Muster: der camelCase-Feldname in GROSSBUCHSTABEN umgewandelt.
Namenskonvention:
| Spaltenname (DB) | Feldname (GraphQL) | GroupBy-Enum-Wert |
|---|---|---|
payment_method | paymentMethod | PAYMENTMETHOD |
created_at | createdAt | CREATEDAT |
status | status | STATUS |
category_id | categoryId | CATEGORYID |
Beispiel: Studenten nach aktivem Status gruppieren
Abschnitt betitelt „Beispiel: Studenten nach aktivem Status gruppieren“Anfrage
query { students(groupBy: [ISACTIVE]) { items { isActive } count }}Antwort
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2 } }}AggregateBy
Abschnitt betitelt „AggregateBy“Das Argument aggregateBy ermöglicht die Berechnung von Aggregationsfunktionen über gruppierte (oder nicht gruppierte) Daten. Jede Aggregation erfordert eine function, ein optionales field und einen obligatorischen alias.
AggregateInput-Struktur
Abschnitt betitelt „AggregateInput-Struktur“input {TableName}AggregateInput { function: AggregateFunction! field: {TableName}AggregateField alias: String!}Verfügbare Aggregationsfunktionen
Abschnitt betitelt „Verfügbare Aggregationsfunktionen“| Funktion | Beschreibung | field erforderlich? |
|---|---|---|
COUNT | Zeilen zählen | Nein (verwendet COUNT(*) wenn weggelassen) |
SUM | Numerische Werte summieren | Ja |
AVG | Durchschnitt berechnen | Ja |
MIN | Minimalwert finden | Ja |
MAX | Maximalwert finden | Ja |
COUNT_DISTINCT | Unterschiedliche Werte zählen | Ja |
Das field-Enum folgt derselben GROSSBUCHSTABEN-Konvention wie GroupBy.
Der alias ist eine Zeichenkette, die Sie zur Benennung des Ergebnisses wählen. Er erscheint als Schlüssel im aggregates-Antwortobjekt.
Beispiel: Anzahl und Durchschnittsalter von Studenten gruppiert nach aktivem Status
Abschnitt betitelt „Beispiel: Anzahl und Durchschnittsalter von Studenten gruppiert nach aktivem Status“Anfrage
query { students( groupBy: [ISACTIVE] aggregateBy: [ { function: COUNT, alias: "totalStudents" } { function: AVG, field: AGE, alias: "avgAge" } ] ) { items { isActive } count aggregates }}Antwort
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2, "aggregates": [ { "totalStudents": 5, "avgAge": 23.4 }, { "totalStudents": 2, "avgAge": 21.0 } ] } }}Jeder Eintrag im aggregates-Array entspricht der Gruppe am gleichen Index in items.
Das Argument having filtert Gruppen basierend auf aggregierten Ergebnissen, entspricht der SQL-Klausel HAVING. Es verwendet einen dedizierten Eingabetyp mit drei Feldern.
HavingFilterInput-Struktur
Abschnitt betitelt „HavingFilterInput-Struktur“input {TableName}HavingFilterInput { alias: String! operator: HavingOperator! value: Float!}alias: Muss mit einem inaggregateBydefinierten Alias übereinstimmen.operator: Der Vergleichsoperator (siehe Tabelle unten).value: Der numerische Schwellenwert zum Vergleichen.
Verfügbare Operatoren
Abschnitt betitelt „Verfügbare Operatoren“| Operator | SQL-Äquivalent |
|---|---|
EQUALS | = |
NOT_EQUALS | != |
GREATER_THAN | > |
GREATER_THAN_OR_EQUAL | >= |
LESS_THAN | < |
LESS_THAN_OR_EQUAL | <= |
Beispiel: Städte mit mehr als 3 Studenten
Abschnitt betitelt „Beispiel: Städte mit mehr als 3 Studenten“Anfrage
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] having: [ { alias: "studentCount", operator: GREATER_THAN, value: 3 } ] ) { items { cityId } count aggregates }}Antwort
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" } ], "count": 1, "aggregates": [ { "studentCount": 5 } ] } }}Nur Gruppen, die die Aggregationsbedingung erfüllen, werden zurückgegeben.
AggregateSort
Abschnitt betitelt „AggregateSort“Das Argument aggregateSort sortiert die gruppierten Ergebnisse nach einem aggregierten Wert anstatt nach einem regulären Feld.
AggregateSortInput-Struktur
Abschnitt betitelt „AggregateSortInput-Struktur“input {TableName}AggregateSortInput { alias: String! direction: SortDirection!}alias: Muss mit einem inaggregateBydefinierten Alias übereinstimmen.direction:ASC(aufsteigend) oderDESC(absteigend).
Beispiel: Top 3 Städte nach Studentenzahl
Abschnitt betitelt „Beispiel: Top 3 Städte nach Studentenzahl“Anfrage
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] aggregateSort: [ { alias: "studentCount", direction: DESC } ] first: 3 ) { items { cityId } count aggregates }}Antwort
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" }, { "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" }, { "cityId": "a2b3c4d5-e6f7-8901-2345-678901234567" } ], "count": 3, "aggregates": [ { "studentCount": 5 }, { "studentCount": 3 }, { "studentCount": 2 } ] } }}Alle Funktionen kombinieren
Abschnitt betitelt „Alle Funktionen kombinieren“Sie können filter, groupBy, aggregateBy, having, aggregateSort und first in einer einzigen Abfrage für komplexe Analysen kombinieren.
Beispiel: Top 5 Städte aktiver Studenten mit Durchschnittsalter über 20, sortiert nach Durchschnittsalter
Abschnitt betitelt „Beispiel: Top 5 Städte aktiver Studenten mit Durchschnittsalter über 20, sortiert nach Durchschnittsalter“Anfrage
query { students( filter: { isActive: { equals: true } } groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } { function: AVG, field: AGE, alias: "avgAge" } { function: MAX, field: AGE, alias: "maxAge" } ] having: [ { alias: "avgAge", operator: GREATER_THAN, value: 20 } ] aggregateSort: [ { alias: "avgAge", direction: DESC } ] first: 5 ) { items { cityId } count aggregates }}Antwort
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" }, { "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" } ], "count": 2, "aggregates": [ { "studentCount": 3, "avgAge": 24.3, "maxAge": 28 }, { "studentCount": 2, "avgAge": 22.5, "maxAge": 25 } ] } }}Diese Abfrage:
- Filtert nur aktive Studenten (
filter). - Gruppiert nach Stadt (
groupBy). - Berechnet Anzahl, Durchschnittsalter und Maximalalter für jede Gruppe (
aggregateBy). - Behält nur Gruppen mit Durchschnittsalter über 20 (
having). - Sortiert nach Durchschnittsalter absteigend (
aggregateSort). - Begrenzt auf die Top 5 Gruppen (
first).
Antwortstruktur
Abschnitt betitelt „Antwortstruktur“Bei Verwendung von Aggregationen folgt die Antwort dem Standard-Connection-Typ mit einem zusätzlichen Feld aggregates:
| Feld | Typ | Beschreibung |
|---|---|---|
items | [{TableName}!]! | Die gruppierten Datensätze (einer pro Gruppe, mit den gruppierten Feldwerten) |
count | Int! | Anzahl der zurückgegebenen Gruppen |
pageInfo | PageInfo! | Paginierungsinfo (hasNextPage, hasPreviousPage) |
aggregates | JSON | Array von Objekten, jeweils mit den berechneten Aggregatwerten nach Alias indexiert |
Das aggregates-Array ist parallel zu items — das Aggregat am Index i entspricht der Gruppe am Index i in items.
Wichtige Hinweise
Abschnitt betitelt „Wichtige Hinweise“- GroupBy- und AggregateField-Enum-Werte verwenden GROSSBUCHSTABEN des camelCase-Feldnamens:
payment_method→paymentMethod→PAYMENTMETHOD. - Having-Aliase müssen übereinstimmen mit einem in
aggregateBydefinierten Alias. Bei Nichtübereinstimmung wird die Having-Bedingung ignoriert. - AggregateSort-Aliase müssen übereinstimmen mit einem in
aggregateBydefinierten Alias. - COUNT ohne field verwendet
COUNT(*), zählt alle Zeilen in der Gruppe. - Mehrere Having-Bedingungen können kombiniert werden — alle müssen erfüllt sein (AND-Logik).
- Mehrere aggregateSort-Einträge werden nach Priorität angewendet (erster Eintrag ist die Hauptsortierung).
- Standard-Paginierungsargumente (
first,skip,after,before) funktionieren mit gruppierten Ergebnissen. - Das filter-Argument wird vor der Gruppierung angewendet (äquivalent zu SQL WHERE), während having nach der Gruppierung angewendet wird (äquivalent zu SQL HAVING).