Grupowanie i Agregacje
Archie Core oferuje potężne możliwości grupowania i agregacji poprzez interfejs API GraphQL. Możesz grupować rekordy według wartości pól, obliczać funkcje agregujące (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT), filtrować grupy za pomocą warunków HAVING i sortować wyniki według wartości zagregowanych.
Argumenty zapytania
Dział zatytułowany „Argumenty zapytania”Przy użyciu grupowania i agregacji następujące argumenty są dostępne w dowolnym zapytaniu listy:
| Argument | Typ | Opis |
|---|---|---|
groupBy | [{TableName}GroupBy] | Pola, według których grupować wyniki |
aggregateBy | [{TableName}AggregateInput] | Funkcje agregujące do obliczenia |
having | [{TableName}HavingFilterInput] | Filtrowanie grup według wyników agregacji |
aggregateSort | [{TableName}AggregateSortInput] | Sortowanie wyników według wartości zagregowanych |
Te argumenty można łączyć ze standardowymi argumentami takimi jak filter, first, skip i orderBy.
GroupBy
Dział zatytułowany „GroupBy”Argument groupBy przyjmuje tablicę wartości enum reprezentujących pola, według których grupować. Wartości enum stosują wzorzec: nazwa pola w camelCase przekonwertowana na WIELKIE_LITERY.
Konwencja nazewnictwa:
| Nazwa kolumny (DB) | Nazwa pola (GraphQL) | Wartość enum GroupBy |
|---|---|---|
payment_method | paymentMethod | PAYMENTMETHOD |
created_at | createdAt | CREATEDAT |
status | status | STATUS |
category_id | categoryId | CATEGORYID |
Przykład: Grupowanie studentów według statusu aktywnego
Dział zatytułowany „Przykład: Grupowanie studentów według statusu aktywnego”Żądanie
query { students(groupBy: [ISACTIVE]) { items { isActive } count }}Odpowiedź
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2 } }}AggregateBy
Dział zatytułowany „AggregateBy”Argument aggregateBy umożliwia obliczanie funkcji agregujących na danych zgrupowanych (lub niezgrupowanych). Każda agregacja wymaga function, opcjonalnego field i obowiązkowego alias.
Struktura AggregateInput
Dział zatytułowany „Struktura AggregateInput”input {TableName}AggregateInput { function: AggregateFunction! field: {TableName}AggregateField alias: String!}Dostępne funkcje agregujące
Dział zatytułowany „Dostępne funkcje agregujące”| Funkcja | Opis | Czy field wymagane? |
|---|---|---|
COUNT | Liczenie wierszy | Nie (używa COUNT(*) gdy pominięte) |
SUM | Sumowanie wartości numerycznych | Tak |
AVG | Obliczanie średniej | Tak |
MIN | Znajdowanie wartości minimalnej | Tak |
MAX | Znajdowanie wartości maksymalnej | Tak |
COUNT_DISTINCT | Liczenie unikalnych wartości | Tak |
Enum field stosuje tę samą konwencję WIELKICH_LITER co GroupBy.
alias to ciąg znaków, który wybierasz do nazwania wyniku. Pojawia się jako klucz w obiekcie odpowiedzi aggregates.
Przykład: Liczenie i uśrednianie wieku studentów zgrupowanych według statusu aktywnego
Dział zatytułowany „Przykład: Liczenie i uśrednianie wieku studentów zgrupowanych według statusu aktywnego”Żądanie
query { students( groupBy: [ISACTIVE] aggregateBy: [ { function: COUNT, alias: "totalStudents" } { function: AVG, field: AGE, alias: "avgAge" } ] ) { items { isActive } count aggregates }}Odpowiedź
{ "data": { "students": { "items": [ { "isActive": true }, { "isActive": false } ], "count": 2, "aggregates": [ { "totalStudents": 5, "avgAge": 23.4 }, { "totalStudents": 2, "avgAge": 21.0 } ] } }}Każdy wpis w tablicy aggregates odpowiada grupie o tym samym indeksie w items.
Argument having filtruje grupy według wyników agregacji, odpowiednik klauzuli SQL HAVING. Używa dedykowanego typu wejściowego z trzema polami.
Struktura HavingFilterInput
Dział zatytułowany „Struktura HavingFilterInput”input {TableName}HavingFilterInput { alias: String! operator: HavingOperator! value: Float!}alias: Musi pasować do aliasu zdefiniowanego waggregateBy.operator: Operator porównania (patrz tabela poniżej).value: Próg numeryczny, z którym porównywać.
Dostępne operatory
Dział zatytułowany „Dostępne operatory”| Operator | Odpowiednik SQL |
|---|---|
EQUALS | = |
NOT_EQUALS | != |
GREATER_THAN | > |
GREATER_THAN_OR_EQUAL | >= |
LESS_THAN | < |
LESS_THAN_OR_EQUAL | <= |
Przykład: Miasta z więcej niż 3 studentami
Dział zatytułowany „Przykład: Miasta z więcej niż 3 studentami”Żądanie
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] having: [ { alias: "studentCount", operator: GREATER_THAN, value: 3 } ] ) { items { cityId } count aggregates }}Odpowiedź
{ "data": { "students": { "items": [ { "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" } ], "count": 1, "aggregates": [ { "studentCount": 5 } ] } }}Zwracane są tylko grupy spełniające warunek agregacji.
AggregateSort
Dział zatytułowany „AggregateSort”Argument aggregateSort sortuje zgrupowane wyniki według wartości zagregowanej, zamiast według zwykłego pola.
Struktura AggregateSortInput
Dział zatytułowany „Struktura AggregateSortInput”input {TableName}AggregateSortInput { alias: String! direction: SortDirection!}alias: Musi pasować do aliasu zdefiniowanego waggregateBy.direction:ASC(rosnąco) lubDESC(malejąco).
Przykład: Top 3 miasta według liczby studentów
Dział zatytułowany „Przykład: Top 3 miasta według liczby studentów”Żądanie
query { students( groupBy: [CITYID] aggregateBy: [ { function: COUNT, alias: "studentCount" } ] aggregateSort: [ { alias: "studentCount", direction: DESC } ] first: 3 ) { items { cityId } count aggregates }}Odpowiedź
{ "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 } ] } }}Łączenie wszystkich funkcji
Dział zatytułowany „Łączenie wszystkich funkcji”Możesz łączyć filter, groupBy, aggregateBy, having, aggregateSort i first w jednym zapytaniu do złożonych analiz.
Przykład: Top 5 miast aktywnych studentów ze średnim wiekiem powyżej 20, posortowane według średniego wieku
Dział zatytułowany „Przykład: Top 5 miast aktywnych studentów ze średnim wiekiem powyżej 20, posortowane według średniego wieku”Żądanie
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 }}Odpowiedź
{ "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 } ] } }}To zapytanie:
- Filtruje tylko aktywnych studentów (
filter). - Grupuje według miasta (
groupBy). - Oblicza liczbę, średni wiek i maksymalny wiek w każdej grupie (
aggregateBy). - Zachowuje tylko grupy ze średnim wiekiem powyżej 20 (
having). - Sortuje według średniego wieku malejąco (
aggregateSort). - Ogranicza do 5 najlepszych grup (
first).
Struktura odpowiedzi
Dział zatytułowany „Struktura odpowiedzi”Przy użyciu agregacji odpowiedź stosuje standardowy typ Connection z dodatkowym polem aggregates:
| Pole | Typ | Opis |
|---|---|---|
items | [{TableName}!]! | Zgrupowane rekordy (jeden na grupę, z wartościami pól zgrupowanych) |
count | Int! | Liczba zwróconych grup |
pageInfo | PageInfo! | Informacje o stronicowaniu (hasNextPage, hasPreviousPage) |
aggregates | JSON | Tablica obiektów, każdy z obliczonymi wartościami zagregowanymi indeksowanymi według aliasu |
Tablica aggregates jest równoległa do items — agregat o indeksie i odpowiada grupie o indeksie i w items.
Ważne uwagi
Dział zatytułowany „Ważne uwagi”- Wartości enum GroupBy i AggregateField używają WIELKICH_LITER nazwy pola w camelCase:
payment_method→paymentMethod→PAYMENTMETHOD. - Aliasy having muszą pasować do aliasu zdefiniowanego w
aggregateBy. Jeśli nie pasują, warunek having jest ignorowany. - Aliasy aggregateSort muszą pasować do aliasu zdefiniowanego w
aggregateBy. - COUNT bez field używa
COUNT(*), licząc wszystkie wiersze w grupie. - Wiele warunków having można łączyć — wszystkie muszą być spełnione (logika AND).
- Wiele wpisów aggregateSort stosuje się w kolejności priorytetu (pierwszy to sortowanie główne).
- Standardowe argumenty stronicowania (
first,skip,after,before) działają ze zgrupowanymi wynikami. - Argument filter stosuje się przed grupowaniem (odpowiednik SQL WHERE), podczas gdy having stosuje się po grupowaniu (odpowiednik SQL HAVING).