Raggruppamento e Aggregazioni
Archie Core offre potenti capacità di raggruppamento e aggregazione tramite la sua API GraphQL. Puoi raggruppare i record per valori di campo, calcolare funzioni di aggregazione (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT), filtrare i gruppi con condizioni HAVING e ordinare i risultati per valori aggregati.
Argomenti della query
Sezione intitolata “Argomenti della query”Quando si utilizzano raggruppamento e aggregazioni, i seguenti argomenti sono disponibili su qualsiasi query di lista:
| Argomento | Tipo | Descrizione |
|---|---|---|
groupBy | [{TableName}GroupBy] | Campi per raggruppare i risultati |
aggregateBy | [{TableName}AggregateInput] | Funzioni di aggregazione da calcolare |
having | [{TableName}HavingFilterInput] | Filtrare i gruppi per risultati aggregati |
aggregateSort | [{TableName}AggregateSortInput] | Ordinare i risultati per valori aggregati |
Questi argomenti possono essere combinati con argomenti standard come filter, first, skip e orderBy.
GroupBy
Sezione intitolata “GroupBy”L’argomento groupBy accetta un array di valori enum che rappresentano i campi per cui raggruppare. I valori enum seguono il modello: il nome del campo in camelCase convertito in MAIUSCOLO.
Convenzione di denominazione:
| Nome colonna (DB) | Nome campo (GraphQL) | Valore enum GroupBy |
|---|---|---|
payment_method | paymentMethod | PAYMENTMETHOD |
created_at | createdAt | CREATEDAT |
status | status | STATUS |
category_id | categoryId | CATEGORYID |
Esempio: Raggruppare studenti per stato attivo
Sezione intitolata “Esempio: Raggruppare studenti per stato attivo”Richiesta
query { students(groupBy: [ISACTIVE]) { items { isActive } count }}Risposta
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2 } }}AggregateBy
Sezione intitolata “AggregateBy”L’argomento aggregateBy consente di calcolare funzioni di aggregazione su dati raggruppati (o non raggruppati). Ogni aggregato richiede una function, un field opzionale e un alias obbligatorio.
Struttura AggregateInput
Sezione intitolata “Struttura AggregateInput”input {TableName}AggregateInput { function: AggregateFunction! field: {TableName}AggregateField alias: String!}Funzioni di aggregazione disponibili
Sezione intitolata “Funzioni di aggregazione disponibili”| Funzione | Descrizione | field richiesto? |
|---|---|---|
COUNT | Contare le righe | No (usa COUNT(*) se omesso) |
SUM | Sommare valori numerici | Sì |
AVG | Calcolare la media | Sì |
MIN | Trovare il valore minimo | Sì |
MAX | Trovare il valore massimo | Sì |
COUNT_DISTINCT | Contare valori distinti | Sì |
L’enum field segue la stessa convenzione MAIUSCOLO di GroupBy.
L’alias è una stringa che scegli per nominare il risultato. Appare come chiave nell’oggetto di risposta aggregates.
Esempio: Contare e mediare l’età degli studenti raggruppati per stato attivo
Sezione intitolata “Esempio: Contare e mediare l’età degli studenti raggruppati per stato attivo”Richiesta
query { students( groupBy: [ISACTIVE] aggregateBy: [ { function: COUNT, alias: "totalStudents" } { function: AVG, field: AGE, alias: "avgAge" } ] ) { items { isActive } count aggregates }}Risposta
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2, "aggregates": [ { "totalStudents": 5, "avgAge": 23.4 }, { "totalStudents": 2, "avgAge": 21.0 } ] } }}Ogni voce nell’array aggregates corrisponde al gruppo allo stesso indice in items.
L’argomento having filtra i gruppi in base ai risultati aggregati, equivalente alla clausola SQL HAVING. Utilizza un tipo di input dedicato con tre campi.
Struttura HavingFilterInput
Sezione intitolata “Struttura HavingFilterInput”input {TableName}HavingFilterInput { alias: String! operator: HavingOperator! value: Float!}alias: Deve corrispondere a un alias definito inaggregateBy.operator: L’operatore di confronto (vedi tabella sotto).value: La soglia numerica da confrontare.
Operatori disponibili
Sezione intitolata “Operatori disponibili”| Operatore | Equivalente SQL |
|---|---|
EQUALS | = |
NOT_EQUALS | != |
GREATER_THAN | > |
GREATER_THAN_OR_EQUAL | >= |
LESS_THAN | < |
LESS_THAN_OR_EQUAL | <= |
Esempio: Città con più di 3 studenti
Sezione intitolata “Esempio: Città con più di 3 studenti”Richiesta
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] having: [ { alias: "studentCount", operator: GREATER_THAN, value: 3 } ] ) { items { cityId } count aggregates }}Risposta
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" } ], "count": 1, "aggregates": [ { "studentCount": 5 } ] } }}Solo i gruppi che soddisfano la condizione di aggregazione vengono restituiti.
AggregateSort
Sezione intitolata “AggregateSort”L’argomento aggregateSort ordina i risultati raggruppati per un valore aggregato, anziché per un campo regolare.
Struttura AggregateSortInput
Sezione intitolata “Struttura AggregateSortInput”input {TableName}AggregateSortInput { alias: String! direction: SortDirection!}alias: Deve corrispondere a un alias definito inaggregateBy.direction:ASC(ascendente) oDESC(discendente).
Esempio: Top 3 città per numero di studenti
Sezione intitolata “Esempio: Top 3 città per numero di studenti”Richiesta
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] aggregateSort: [ { alias: "studentCount", direction: DESC } ] first: 3 ) { items { cityId } count aggregates }}Risposta
{ "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 } ] } }}Combinare tutte le funzionalità
Sezione intitolata “Combinare tutte le funzionalità”Puoi combinare filter, groupBy, aggregateBy, having, aggregateSort e first in una singola query per analisi complesse.
Esempio: Top 5 città di studenti attivi con età media superiore a 20, ordinate per età media
Sezione intitolata “Esempio: Top 5 città di studenti attivi con età media superiore a 20, ordinate per età media”Richiesta
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 }}Risposta
{ "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 } ] } }}Questa query:
- Filtra solo studenti attivi (
filter). - Raggruppa per città (
groupBy). - Calcola conteo, età media e età massima per ogni gruppo (
aggregateBy). - Mantiene solo gruppi con età media superiore a 20 (
having). - Ordina per età media decrescente (
aggregateSort). - Limita ai primi 5 gruppi (
first).
Struttura della risposta
Sezione intitolata “Struttura della risposta”Quando si utilizzano le aggregazioni, la risposta segue il tipo Connection standard con un campo aggiuntivo aggregates:
| Campo | Tipo | Descrizione |
|---|---|---|
items | [{TableName}!]! | I record raggruppati (uno per gruppo, contenente i valori dei campi raggruppati) |
count | Int! | Numero di gruppi restituiti |
pageInfo | PageInfo! | Info paginazione (hasNextPage, hasPreviousPage) |
aggregates | JSON | Array di oggetti, ciascuno contenente i valori aggregati calcolati indicizzati per alias |
L’array aggregates è parallelo a items — l’aggregato all’indice i corrisponde al gruppo all’indice i in items.
Note importanti
Sezione intitolata “Note importanti”- I valori enum GroupBy e AggregateField usano MAIUSCOLO del nome del campo in camelCase:
payment_method→paymentMethod→PAYMENTMETHOD. - Gli alias having devono corrispondere a un alias definito in
aggregateBy. Se non corrisponde, la condizione having viene ignorata. - Gli alias aggregateSort devono corrispondere a un alias definito in
aggregateBy. - COUNT senza field usa
COUNT(*), contando tutte le righe nel gruppo. - Più condizioni having possono essere combinate — tutte devono essere soddisfatte (logica AND).
- Più voci aggregateSort sono applicate in ordine di priorità (la prima è l’ordinamento principale).
- Gli argomenti di paginazione standard (
first,skip,after,before) funzionano con i risultati raggruppati. - L’argomento filter viene applicato prima del raggruppamento (equivalente a SQL WHERE), mentre having viene applicato dopo il raggruppamento (equivalente a SQL HAVING).