Agrupamento e Agregações
O Archie Core oferece capacidades poderosas de agrupamento e agregação através da sua API GraphQL. Você pode agrupar registros por valores de campos, calcular funções de agregação (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT), filtrar grupos com condições HAVING e ordenar resultados por valores agregados.
Argumentos da query
Seção intitulada “Argumentos da query”Ao usar agrupamento e agregações, os seguintes argumentos estão disponíveis em qualquer query de lista:
| Argumento | Tipo | Descrição |
|---|---|---|
groupBy | [{TableName}GroupBy] | Campos para agrupar resultados |
aggregateBy | [{TableName}AggregateInput] | Funções de agregação a calcular |
having | [{TableName}HavingFilterInput] | Filtrar grupos por resultados agregados |
aggregateSort | [{TableName}AggregateSortInput] | Ordenar resultados por valores agregados |
Estes argumentos podem ser combinados com argumentos padrão como filter, first, skip e orderBy.
GroupBy
Seção intitulada “GroupBy”O argumento groupBy aceita um array de valores enum que representam os campos a agrupar. Os valores enum seguem o padrão: o nome do campo em camelCase convertido em MAIÚSCULAS.
Convenção de nomenclatura:
| Nome da coluna (DB) | Nome do campo (GraphQL) | Valor enum GroupBy |
|---|---|---|
payment_method | paymentMethod | PAYMENTMETHOD |
created_at | createdAt | CREATEDAT |
status | status | STATUS |
category_id | categoryId | CATEGORYID |
Exemplo: Agrupar estudantes por estado ativo
Seção intitulada “Exemplo: Agrupar estudantes por estado ativo”Requisição
query { students(groupBy: [ISACTIVE]) { items { isActive } count }}Resposta
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2 } }}AggregateBy
Seção intitulada “AggregateBy”O argumento aggregateBy permite calcular funções de agregação sobre dados agrupados (ou não). Cada agregado requer uma function, um field opcional e um alias obrigatório.
Estrutura AggregateInput
Seção intitulada “Estrutura AggregateInput”input {TableName}AggregateInput { function: AggregateFunction! field: {TableName}AggregateField alias: String!}Funções de agregação disponíveis
Seção intitulada “Funções de agregação disponíveis”| Função | Descrição | field obrigatório? |
|---|---|---|
COUNT | Contar linhas | Não (usa COUNT(*) quando omitido) |
SUM | Somar valores numéricos | Sim |
AVG | Calcular média | Sim |
MIN | Encontrar valor mínimo | Sim |
MAX | Encontrar valor máximo | Sim |
COUNT_DISTINCT | Contar valores distintos | Sim |
O enum field segue a mesma convenção MAIÚSCULAS que GroupBy.
O alias é uma string que você escolhe para nomear o resultado. Aparece como chave no objeto de resposta aggregates.
Exemplo: Contar e calcular média de idade de estudantes agrupados por estado ativo
Seção intitulada “Exemplo: Contar e calcular média de idade de estudantes agrupados por estado ativo”Requisição
query { students( groupBy: [ISACTIVE] aggregateBy: [ { function: COUNT, alias: "totalStudents" } { function: AVG, field: AGE, alias: "avgAge" } ] ) { items { isActive } count aggregates }}Resposta
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2, "aggregates": [ { "totalStudents": 5, "avgAge": 23.4 }, { "totalStudents": 2, "avgAge": 21.0 } ] } }}Cada entrada no array aggregates corresponde ao grupo no mesmo índice em items.
O argumento having filtra grupos com base em resultados agregados, equivalente à cláusula SQL HAVING. Utiliza um tipo de entrada dedicado com três campos.
Estrutura HavingFilterInput
Seção intitulada “Estrutura HavingFilterInput”input {TableName}HavingFilterInput { alias: String! operator: HavingOperator! value: Float!}alias: Deve corresponder a um alias definido emaggregateBy.operator: O operador de comparação (ver tabela abaixo).value: O limiar numérico a comparar.
Operadores disponíveis
Seção intitulada “Operadores disponíveis”| Operador | Equivalente SQL |
|---|---|
EQUALS | = |
NOT_EQUALS | != |
GREATER_THAN | > |
GREATER_THAN_OR_EQUAL | >= |
LESS_THAN | < |
LESS_THAN_OR_EQUAL | <= |
Exemplo: Cidades com mais de 3 estudantes
Seção intitulada “Exemplo: Cidades com mais de 3 estudantes”Requisição
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] having: [ { alias: "studentCount", operator: GREATER_THAN, value: 3 } ] ) { items { cityId } count aggregates }}Resposta
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" } ], "count": 1, "aggregates": [ { "studentCount": 5 } ] } }}Apenas grupos que satisfazem a condição de agregação são retornados.
AggregateSort
Seção intitulada “AggregateSort”O argumento aggregateSort ordena os resultados agrupados por um valor agregado, em vez de por um campo regular.
Estrutura AggregateSortInput
Seção intitulada “Estrutura AggregateSortInput”input {TableName}AggregateSortInput { alias: String! direction: SortDirection!}alias: Deve corresponder a um alias definido emaggregateBy.direction:ASC(ascendente) ouDESC(descendente).
Exemplo: Top 3 cidades por número de estudantes
Seção intitulada “Exemplo: Top 3 cidades por número de estudantes”Requisição
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] aggregateSort: [ { alias: "studentCount", direction: DESC } ] first: 3 ) { items { cityId } count aggregates }}Resposta
{ "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 } ] } }}Combinar todas as funcionalidades
Seção intitulada “Combinar todas as funcionalidades”Você pode combinar filter, groupBy, aggregateBy, having, aggregateSort e first em uma única query para análises complexas.
Exemplo: Top 5 cidades de estudantes ativos com idade média acima de 20, ordenadas por idade média
Seção intitulada “Exemplo: Top 5 cidades de estudantes ativos com idade média acima de 20, ordenadas por idade média”Requisição
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 }}Resposta
{ "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 } ] } }}Esta query:
- Filtra apenas estudantes ativos (
filter). - Agrupa por cidade (
groupBy). - Calcula contagem, idade média e idade máxima para cada grupo (
aggregateBy). - Mantém apenas grupos com idade média acima de 20 (
having). - Ordena por idade média descendente (
aggregateSort). - Limita aos 5 primeiros grupos (
first).
Estrutura da resposta
Seção intitulada “Estrutura da resposta”Ao usar agregações, a resposta segue o tipo Connection padrão com um campo adicional aggregates:
| Campo | Tipo | Descrição |
|---|---|---|
items | [{TableName}!]! | Os registros agrupados (um por grupo, contendo os valores dos campos agrupados) |
count | Int! | Número de grupos retornados |
pageInfo | PageInfo! | Info de paginação (hasNextPage, hasPreviousPage) |
aggregates | JSON | Array de objetos, cada um contendo os valores agregados calculados indexados por alias |
O array aggregates é paralelo a items — o agregado no índice i corresponde ao grupo no índice i em items.
Notas importantes
Seção intitulada “Notas importantes”- Os valores enum GroupBy e AggregateField usam MAIÚSCULAS do nome do campo em camelCase:
payment_method→paymentMethod→PAYMENTMETHOD. - Os alias having devem corresponder a um alias definido em
aggregateBy. Se não corresponder, a condição having é ignorada. - Os alias aggregateSort devem corresponder a um alias definido em
aggregateBy. - COUNT sem field usa
COUNT(*), contando todas as linhas no grupo. - Múltiplas condições having podem ser combinadas — todas devem ser satisfeitas (lógica AND).
- Múltiplas entradas aggregateSort são aplicadas por ordem de prioridade (a primeira é a ordenação principal).
- Os argumentos de paginação padrão (
first,skip,after,before) funcionam com resultados agrupados. - O argumento filter é aplicado antes do agrupamento (equivalente a SQL WHERE), enquanto having é aplicado após o agrupamento (equivalente a SQL HAVING).