Agregowanie danych z tablicy
Zapytanie aggregate pozwala obliczyć zbiorcze statystyki z tablicy monday.com w jednym wywołaniu API. Zamiast pobierać wszystkie elementy, stronicować wyniki i obliczać sumy w swoim kodzie, możesz zlecić to API.
W tym przewodniku poznasz zapytanie aggregate - od podstawowego zliczania po zaawansowane grupowanie i filtrowanie. Po jego przeczytaniu będziesz umieć tworzyć pulpity, generować raporty i wyciągać wnioski bez pobierania surowych danych o elementach.
Dlaczego warto używać aggregate?
Problem z zapytaniami pobierającymi surowe dane o elementach
Przed wprowadzeniem aggregate uzyskanie zbiorczych danych z tablicy wymagało kilku kroków:
- Pobranie elementów za pomocą
items_page(i stronicowanie, jeśli tablica zawiera więcej niż 500 elementów) - Obsługa limitów szybkości i limitów złożoności dla wielu stron wyników
- Analiza wartości kolumn w formacie odpowiedzi API
- Obliczenie podsumowania (liczby, sumy, średniej itp.) w kodzie aplikacji
W przypadku tablicy zawierającej ponad 1000 elementów mogło to wymagać co najmniej 3 wywołań API i tysięcy punktów złożoności.
Zalety aggregate
Dzięki aggregate wszystkie te kroki sprowadzają się do jednego:
| Surowe zapytania o elementy | Aggregate | |
|---|---|---|
| Wywołania API | Co najmniej 3 (stronicowanie) | 1 |
| Koszt złożoności | Ponad 5500 na stronę | Łącznie około 110 |
| Kod po stronie klienta | Analiza wartości, sumowanie i obliczenia | Odczyt wyniku |
| Opóźnienie | Wielokrotne zapytania i odpowiedzi | Jedno zapytanie i odpowiedź |
| Przesyłane dane | Pełne dane elementów | Tylko wartości podsumowania |
👍 Przykład z praktyki
Dla tablicy zawierającej 1368 elementów zmierzyliśmy, że aggregate z 3 funkcjami kosztuje 110 punktów złożoności. Pojedyncze wywołanie
items_pagedla 500 elementów i 1 kolumny kosztowało 5520 punktów - a to dopiero pierwsza z 3 potrzebnych stron. Pełne pobranie elementów kosztowałoby około 16 560 punktów, więc aggregate jest około 150 razy tańsze.
Kto skorzysta najbardziej
Twórcy aplikacji prywatnych, którzy budują narzędzia wewnętrzne: - Sprawdzanie produktywności zespołu: policz elementy ukończone w ciągu ostatnich 90 dni - Określanie wielkości lejka sprzedażowego: zsumuj wartość szans sprzedaży, grupując je według etapu - Śledzenie kondycji projektu: oblicz średni czas ukończenia na podstawie kolumny z formułą
Twórcy aplikacji publicznych, którzy publikują je w marketplace: - Pulpity do śledzenia czasu: pokaż średni zarejestrowany czas pracy poszczególnych osób - Równoważenie obciążenia pracą: znajdź członka zespołu z najmniejszą liczbą przypisanych zadań - Wnioski generowane przez AI: przekaż zagregowane dane do LLM w celu analizy
Pierwsze kroki
Wymagania wstępne
- Token uwierzytelniający API
- Identyfikator tablicy (znajdziesz go w adresie URL:
monday.com/boards/{board_id}) - Znajomość identyfikatorów kolumn na tablicy (wyślij zapytanie
boards→columns→id)
Pierwsze zapytanie aggregate
Policzmy elementy na tablicy:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{
type: FUNCTION,
function: { function: COUNT_ITEMS },
as: "total_items"
}
]
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
}
}
}
}
}
Odpowiedź:
{
"data": {
"aggregate": {
"results": [
{
"entries": [
{
"alias": "total_items",
"value": {
"result": 1368
}
}
]
}
]
}
}
}
Ważne informacje:
- from wskazuje tablicę za pomocą jej identyfikatora i type: TABLE
- select to tablica wartości, które chcesz obliczyć
- Każdy element select wymaga aliasu as - stanie się on polem alias w odpowiedzi
- Wyniki wykorzystują fragment AggregateBasicAggregationResult, aby zwrócić wartość liczbową result
Funkcje agregujące
Funkcje, które nie wymagają kolumny
Te funkcje działają na elementach:
| Funkcja | Zwracana wartość |
|---|---|
COUNT_ITEMS |
Łączna liczba elementów |
COUNT_SUBITEMS |
Łączna liczba podelementów we wszystkich elementach |
Funkcje, które wymagają kolumny
Te funkcje wymagają argumentu params, który wskazuje kolumnę do agregacji:
| Funkcja | Zwracana wartość |
|---|---|
SUM |
Suma wszystkich wartości liczbowych |
AVERAGE |
Średnia wszystkich wartości liczbowych |
MEDIAN |
Mediana |
MIN |
Wartość minimalna (działa z liczbami i datami) |
MAX |
Wartość maksymalna (działa z liczbami i datami) |
COUNT |
Liczba elementów, w których kolumna ma wartość inną niż null |
COUNT_DISTINCT |
Liczba unikalnych wartości w kolumnie |
Składnia parametrów kolumny
Używając funkcji działającej na kolumnie, przekaż kolumnę jako element params:
{
type: FUNCTION,
function: {
function: SUM,
params: [{
type: COLUMN,
column: { column_id: "numbers_col" },
as: "numbers_col"
}]
},
as: "total_value"
}
Wartość as wewnątrz params powinna odpowiadać wartości column_id. Zewnętrzny alias as to własny alias wyniku.
Uruchamianie wielu funkcji jednocześnie
Możesz obliczyć kilka wskaźników w jednym wywołaniu, dodając kolejne elementy do select:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{
type: FUNCTION,
function: { function: SUM, params: [{ type: COLUMN, column: { column_id: "numbers" }, as: "numbers" }] },
as: "total"
},
{
type: FUNCTION,
function: { function: AVERAGE, params: [{ type: COLUMN, column: { column_id: "numbers" }, as: "numbers" }] },
as: "average"
},
{
type: FUNCTION,
function: { function: MIN, params: [{ type: COLUMN, column: { column_id: "numbers" }, as: "numbers" }] },
as: "minimum"
},
{
type: FUNCTION,
function: { function: MAX, params: [{ type: COLUMN, column: { column_id: "numbers" }, as: "numbers" }] },
as: "maximum"
}
]
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
}
}
}
}
}
Obsługiwane typy kolumn
Nie wszystkie typy kolumn współpracują ze wszystkimi funkcjami. Oto obsługiwane kombinacje:
| Typ kolumny | COUNT | SUM | AVERAGE | MIN | MAX | MEDIAN |
|---|---|---|---|---|---|---|
| Liczby | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Formuła (liczbowa) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ocena | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Data | ✅ | - | - | ✅ | ✅ | - |
| Status | ✅ | - | - | - | - | - |
| Osoby | ✅ | - | - | - | - | - |
| Tekst | ✅ | - | - | - | - | - |
| Pole wyboru | ✅ | - | - | - | - | - |
📘 UWAGA
COUNTiCOUNT_DISTINCTdziałają z każdym typem kolumny.COUNTzwraca liczbę elementów, w których kolumna ma wartość inną niż null.COUNT_DISTINCTzlicza unikalne wartości (najlepiej sprawdza się w przypadku kolumn tekstowych i liczbowych).
Filtrowanie agregacji
Możesz agregować podzbiór elementów, dodając argument query z regułami filtrowania. Składnia filtrowania jest taka sama jak w przypadku filtrowania items_page.
Pojedynczy filtr
Policz elementy ze statusem „Gotowe” (indeks etykiety statusu 1):
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "done_count" }],
query: {
rules: [{
column_id: "status",
compare_value: [1],
operator: any_of
}]
}
}) {
results {
entries {
alias
value { ... on AggregateBasicAggregationResult { result } }
}
}
}
}
Wiele filtrów
Połącz filtry, aby zawęzić wyniki. Policz elementy o priorytecie „Krytyczny” i statusie „Gotowe”, a także oblicz średni szacowany czas ich wykonania:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{
type: FUNCTION,
function: { function: AVERAGE, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "avg_estimation"
}
],
query: {
rules: [
{ column_id: "task_status", compare_value: [1], operator: any_of },
{ column_id: "task_priority", compare_value: [0], operator: any_of }
]
}
}) {
results {
entries {
alias
value { ... on AggregateBasicAggregationResult { result } }
}
}
}
}
Grupowanie za pomocą group_by
Argument group_by dzieli wyniki agregacji na kategorie. Pozwala znaleźć odpowiedzi na pytania takie jak „Jaka jest średnia wartość transakcji dla każdego przedstawiciela handlowego?” lub „Jaka jest liczba elementów dla każdego statusu?”.
Podstawowe grupowanie
Aby pogrupować wyniki:
- Dodaj kolumnę do
group_byi określ przezlimitliczbę zwracanych grup - Dodaj tę samą kolumnę do
selectz wartościątype: COLUMN - Odpytaj
AggregateGroupByResult, aby uzyskać wartość grupy
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{ type: COLUMN, column: { column_id: "task_status" }, as: "task_status" }
],
group_by: [{ column_id: "task_status", limit: 15 }]
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
... on AggregateGroupByResult { value }
}
}
}
}
}
Każdy zestaw wyników w odpowiedzi odpowiada jednej grupie:
{
"data": {
"aggregate": {
"results": [
{
"entries": [
{ "alias": "count", "value": { "result": 792 } },
{ "alias": "task_status", "value": { "value": "#00c875" } }
]
},
{
"entries": [
{ "alias": "count", "value": { "result": 89 } },
{ "alias": "task_status", "value": { "value": "#fdab3d" } }
]
}
]
}
}
}
Interpretowanie wartości grupowania
Pole value w AggregateGroupByResult zwraca surową wartość wewnętrzną, która zależy od typu kolumny:
| Typ kolumny | Format wartości | Przykład | Jak odczytać |
|---|---|---|---|
| Status | Kod koloru w formacie szesnastkowym | "#00c875" |
Dopasuj kod do settings.labels kolumny, aby uzyskać tekst etykiety |
| Osoby | Identyfikator osoby | "person-12345" |
Wyślij zapytanie users(ids: 12345), aby uzyskać imię i nazwisko |
| Pole wyboru | Wartość logiczna | true |
Użyj bezpośrednio |
| Tekst | Zwykły tekst | "Category A" |
Użyj bezpośrednio |
| Data | Czas epoki w milisekundach | 1768435200000 |
Przekonwertuj: new Date(1768435200000) → 2026-01-15 |
| Liczby | Liczba | 42 |
Użyj bezpośrednio |
👍 Wskazówka
Aby dopasować kody szesnastkowe statusów do etykiet, wyślij zapytanie
boards(ids: BOARD_ID) { columns { id settings_str } }i przeanalizuj tablicęlabelsw ustawieniach kolumny statusu. Każda etykieta ma wartośćcolor(indeks koloru) ilabel(tekst).
Grupowanie według wielu kolumn
Możesz grupować według wielu kolumn, aby utworzyć tabele krzyżowe:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{ type: COLUMN, column: { column_id: "task_status" }, as: "task_status" },
{ type: COLUMN, column: { column_id: "task_type" }, as: "task_type" }
],
group_by: [
{ column_id: "task_status", limit: 5 },
{ column_id: "task_type", limit: 5 }
]
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
... on AggregateGroupByResult { value }
}
}
}
}
}
Zwraca to jeden zestaw wyników dla każdej unikalnej kombinacji statusu i typu.
Łączenie grupowania z filtrami
Możesz filtrować elementy przed ich pogrupowaniem. Na przykład oblicz sumę punktów historyjek według typu zadania, uwzględniając tylko ukończone elementy:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{
type: FUNCTION,
function: { function: SUM, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "total_sp"
},
{ type: COLUMN, column: { column_id: "task_type" }, as: "task_type" }
],
group_by: [{ column_id: "task_type", limit: 20 }],
query: { rules: [{ column_id: "task_status", compare_value: [1], operator: any_of }] }
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
... on AggregateGroupByResult { value }
}
}
}
}
}
Grupowanie dat za pomocą DATE_TRUNC
Grupowanie według surowych dat tworzy osobną grupę dla każdej unikalnej daty, co rzadko jest przydatne. Użyj funkcji DATE_TRUNC_*, aby pogrupować daty w użyteczne przedziały czasu.
Przykład grupowania miesięcznego
Policz elementy utworzone w poszczególnych miesiącach:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{
type: FUNCTION,
function: {
function: DATE_TRUNC_MONTH,
params: [{ type: COLUMN, column: { column_id: "date_col" }, as: "month" }]
},
as: "month"
}
],
group_by: [{ column_id: "month", limit: 12 }]
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
... on AggregateGroupByResult { value }
}
}
}
}
}
Alias as w parametrach DATE_TRUNC_MONTH ("month") musi odpowiadać wartości column_id w group_by. Daty są zwracane jako znaczniki czasu epoki w milisekundach.
Dostępne funkcje obcinania dat:
| Funkcja | Grupowanie według |
|---|---|
DATE_TRUNC_DAY |
Dnia kalendarzowego |
DATE_TRUNC_WEEK |
Tygodnia kalendarzowego |
DATE_TRUNC_MONTH |
Miesiąca kalendarzowego |
DATE_TRUNC_QUARTER |
Kwartału kalendarzowego |
DATE_TRUNC_YEAR |
Roku kalendarzowego |
Przykłady praktyczne
Przykład 1: Pulpit obciążenia pracą zespołu
Pokaż liczbę zadań i łączną liczbę punktów historyjek dla każdego członka zespołu:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "tasks" },
{
type: FUNCTION,
function: { function: SUM, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "total_sp"
},
{ type: COLUMN, column: { column_id: "task_owner" }, as: "task_owner" }
],
group_by: [{ column_id: "task_owner", limit: 50 }],
query: { rules: [{ column_id: "task_status", compare_value: [0], operator: any_of }] }
}) {
results {
entries {
alias
value {
... on AggregateBasicAggregationResult { result }
... on AggregateGroupByResult { value }
}
}
}
}
}
Przykład 2: Sprawdzanie kondycji tablicy
Uzyskaj kompleksowy przegląd tablicy za pomocą jednego zapytania:
{
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "total_items" },
{ type: FUNCTION, function: { function: COUNT_SUBITEMS }, as: "total_subitems" },
{
type: FUNCTION,
function: { function: COUNT, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "items_with_estimates"
},
{
type: FUNCTION,
function: { function: SUM, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "total_sp"
},
{
type: FUNCTION,
function: { function: AVERAGE, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "avg_sp"
},
{
type: FUNCTION,
function: { function: MEDIAN, params: [{ type: COLUMN, column: { column_id: "task_estimation" }, as: "task_estimation" }] },
as: "median_sp"
}
]
}) {
results {
entries {
alias
value { ... on AggregateBasicAggregationResult { result } }
}
}
}
}
Przykład 3: Sprawdzanie kosztu złożoności
Dodaj complexity, aby sprawdzić koszt zapytania aggregate:
{
complexity { before after query }
aggregate(query: {
from: { type: TABLE, id: 1234567890 },
select: [
{ type: FUNCTION, function: { function: COUNT_ITEMS }, as: "count" },
{
type: FUNCTION,
function: { function: AVERAGE, params: [{ type: COLUMN, column: { column_id: "numbers" }, as: "numbers" }] },
as: "average"
}
]
}) {
results {
entries {
alias
value { ... on AggregateBasicAggregationResult { result } }
}
}
}
}
Ważne informacje
Obsługa wartości null
Jeśli grupa nie zawiera żadnych wartości innych niż null dla agregowanej kolumny, wynikiem będzie null, a nie 0:
{ "alias": "sum_sp", "value": { "value": null } }
Twoja aplikacja powinna obsługiwać taki przypadek.
Kolejność wyników
Wpisy w każdym zestawie wyników są zwracane alfabetycznie według aliasu, a nie w kolejności określonej w select. Odpowiednio dobierz aliasy lub posortuj wyniki po stronie klienta.
Parametr limit
Parametr limit w AggregateQueryInput określa maksymalną liczbę grup wyników przy użyciu group_by. Nie ma wpływu na agregacje bez grupowania (zawsze zwracają jeden zestaw wyników). Parametr limit w AggregateGroupByElementInput określa, ile unikalnych wartości może mieć każda kolumna użyta do grupowania.
COUNT a COUNT_ITEMS i COUNT_DISTINCT
| Funkcja | Wymaga kolumny | Co zlicza |
|---|---|---|
COUNT_ITEMS |
Nie | Każdy element na tablicy (lub spełniający warunki filtra) |
COUNT |
Tak | Elementy, w których wskazana kolumna ma wartość inną niż null |
COUNT_DISTINCT |
Tak | Unikalne wartości inne niż null w kolumnie |
Następne kroki
- Dokumentacja Aggregate - pełna dokumentacja schematu i typów
- Inne typy Aggregate - szczegóły dotyczące typów wejściowych i wynikowych
- Filtrowanie Items page - składnia filtrowania używana w argumencie
query - Złożoność - informacje o limitach złożoności API
Jeśli masz pytania, zadaj je w społeczności monday dla deweloperów.