Ga naar inhoud

Groepering en Aggregaties

Archie Core biedt krachtige groeperings- en aggregatie- mogelijkheden via zijn GraphQL API. U kunt records groeperen op veldwaarden, aggregatiefuncties berekenen (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT), groepen filteren met HAVING-condities en resultaten sorteren op geaggregeerde waarden.

Bij het gebruik van groepering en aggregaties zijn de volgende argumenten beschikbaar voor elke lijstquery:

ArgumentTypeBeschrijving
groupBy[{TableName}GroupBy]Velden om resultaten te groeperen
aggregateBy[{TableName}AggregateInput]Te berekenen aggregatiefuncties
having[{TableName}HavingFilterInput]Groepen filteren op geaggregeerde resultaten
aggregateSort[{TableName}AggregateSortInput]Resultaten sorteren op geaggregeerde waarden

Deze argumenten kunnen worden gecombineerd met standaardargumenten zoals filter, first, skip en orderBy.

Het argument groupBy accepteert een array van enum-waarden die de te groeperen velden vertegenwoordigen. Enum-waarden volgen het patroon: de camelCase veldnaam in HOOFDLETTERS omgezet.

Naamgevingsconventie:

Kolomnaam (DB)Veldnaam (GraphQL)GroupBy enum-waarde
payment_methodpaymentMethodPAYMENTMETHOD
created_atcreatedAtCREATEDAT
statusstatusSTATUS
category_idcategoryIdCATEGORYID

Voorbeeld: Studenten groeperen op actieve status

Section titled “Voorbeeld: Studenten groeperen op actieve status”

Verzoek

query {
students(groupBy: [ISACTIVE]) {
items {
isActive
}
count
}
}

Antwoord

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2
}
}
}

Het argument aggregateBy maakt het mogelijk om aggregatiefuncties te berekenen over gegroepeerde (of niet-gegroepeerde) gegevens. Elke aggregatie vereist een function, een optioneel field en een verplichte alias.

input {TableName}AggregateInput {
function: AggregateFunction!
field: {TableName}AggregateField
alias: String!
}
FunctieBeschrijvingfield vereist?
COUNTRijen tellenNee (gebruikt COUNT(*) wanneer weggelaten)
SUMNumerieke waarden optellenJa
AVGGemiddelde berekenenJa
MINMinimale waarde vindenJa
MAXMaximale waarde vindenJa
COUNT_DISTINCTUnieke waarden tellenJa

Het field-enum volgt dezelfde HOOFDLETTERS-conventie als GroupBy.

De alias is een string die u kiest om het resultaat te benoemen. Het verschijnt als sleutel in het aggregates-antwoordobject.

Voorbeeld: Aantal en gemiddelde leeftijd van studenten gegroepeerd op actieve status

Section titled “Voorbeeld: Aantal en gemiddelde leeftijd van studenten gegroepeerd op actieve status”

Verzoek

query {
students(
groupBy: [ISACTIVE]
aggregateBy: [
{ function: COUNT, alias: "totalStudents" }
{ function: AVG, field: AGE, alias: "avgAge" }
]
) {
items {
isActive
}
count
aggregates
}
}

Antwoord

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2,
"aggregates": [
{ "totalStudents": 5, "avgAge": 23.4 },
{ "totalStudents": 2, "avgAge": 21.0 }
]
}
}
}

Elk item in de aggregates-array correspondeert met de groep op dezelfde index in items.

Het argument having filtert groepen op basis van geaggregeerde resultaten, equivalent aan de SQL-clausule HAVING. Het gebruikt een specifiek invoertype met drie velden.

input {TableName}HavingFilterInput {
alias: String!
operator: HavingOperator!
value: Float!
}
  • alias: Moet overeenkomen met een alias gedefinieerd in aggregateBy.
  • operator: De vergelijkingsoperator (zie tabel hieronder).
  • value: De numerieke drempel voor vergelijking.
OperatorSQL-equivalent
EQUALS=
NOT_EQUALS!=
GREATER_THAN>
GREATER_THAN_OR_EQUAL>=
LESS_THAN<
LESS_THAN_OR_EQUAL<=

Voorbeeld: Steden met meer dan 3 studenten

Section titled “Voorbeeld: Steden met meer dan 3 studenten”

Verzoek

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
having: [
{ alias: "studentCount", operator: GREATER_THAN, value: 3 }
]
) {
items {
cityId
}
count
aggregates
}
}

Antwoord

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" }
],
"count": 1,
"aggregates": [
{ "studentCount": 5 }
]
}
}
}

Alleen groepen die aan de aggregatievoorwaarde voldoen zijn teruggegeven.

Het argument aggregateSort sorteert de gegroepeerde resultaten op een geaggregeerde waarde in plaats van op een regulier veld.

input {TableName}AggregateSortInput {
alias: String!
direction: SortDirection!
}
  • alias: Moet overeenkomen met een alias gedefinieerd in aggregateBy.
  • direction: ASC (oplopend) of DESC (aflopend).

Voorbeeld: Top 3 steden op aantal studenten

Section titled “Voorbeeld: Top 3 steden op aantal studenten”

Verzoek

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
aggregateSort: [
{ alias: "studentCount", direction: DESC }
]
first: 3
) {
items {
cityId
}
count
aggregates
}
}

Antwoord

{
"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 }
]
}
}
}

U kunt filter, groupBy, aggregateBy, having, aggregateSort en first combineren in één query voor complexe analyses.

Voorbeeld: Top 5 steden van actieve studenten met gemiddelde leeftijd boven 20, gesorteerd op gemiddelde leeftijd

Section titled “Voorbeeld: Top 5 steden van actieve studenten met gemiddelde leeftijd boven 20, gesorteerd op gemiddelde leeftijd”

Verzoek

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
}
}

Antwoord

{
"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 }
]
}
}
}

Deze query:

  1. Filtert alleen actieve studenten (filter).
  2. Groepeert op stad (groupBy).
  3. Berekent aantal, gemiddelde leeftijd en maximale leeftijd per groep (aggregateBy).
  4. Behoudt alleen groepen met gemiddelde leeftijd boven 20 (having).
  5. Sorteert op gemiddelde leeftijd aflopend (aggregateSort).
  6. Beperkt tot de top 5 groepen (first).

Bij gebruik van aggregaties volgt het antwoord het standaard Connection-type met een extra veld aggregates:

VeldTypeBeschrijving
items[{TableName}!]!De gegroepeerde records (één per groep, met de gegroepeerde veldwaarden)
countInt!Aantal geretourneerde groepen
pageInfoPageInfo!Paginatie-info (hasNextPage, hasPreviousPage)
aggregatesJSONArray van objecten, elk met de berekende geaggregeerde waarden geïndexeerd op alias

De aggregates-array is parallel aan items — de aggregatie op index i correspondeert met de groep op index i in items.

  • GroupBy- en AggregateField-enumwaarden gebruiken HOOFDLETTERS van de camelCase veldnaam: payment_methodpaymentMethodPAYMENTMETHOD.
  • Having-alias moet overeenkomen met een alias gedefinieerd in aggregateBy. Als de alias niet overeenkomt, wordt de having-voorwaarde genegeerd.
  • AggregateSort-alias moet overeenkomen met een alias gedefinieerd in aggregateBy.
  • COUNT zonder field gebruikt COUNT(*), telt alle rijen in de groep.
  • Meerdere having-voorwaarden kunnen worden gecombineerd — alle moeten worden voldaan (AND-logica).
  • Meerdere aggregateSort-vermeldingen worden toegepast op prioriteitsvolgorde (eerste vermelding is de primaire sortering).
  • Standaard paginatie-argumenten (first, skip, after, before) werken met gegroepeerde resultaten.
  • Het filter-argument wordt toegepast vóór groepering (equivalent aan SQL WHERE), terwijl having wordt toegepast na groepering (equivalent aan SQL HAVING).