Aggregate records
An aggregation turns matching records into compact summary rows. Use it to count records, compare groups, or calculate numeric values without transferring every source row to the application.
The SDKs use aggregate(). REST uses _aggregate on the ordinary table data
route. Refine uses useList with meta.aggregate, meta.groupBy, and
meta.having. Register its provider,
import useList from @refinedev/core, and place the hook inside a component
beneath <Refine>. Keep pagination off for these aggregate result sets.
Use the aggregate forms listed on this page: count(*) or function(field).
Compose business calculations from returned aggregate values in application
code.
Aggregate reads return a summary result set rather than a page of source
records. An ungrouped aggregate returns one summary row; a grouped aggregate
returns all matching groups and reports the number of returned groups as
total. Use root-table filters and low-cardinality group fields to keep that
result bounded.
Count every record#
count(*) returns one summary row and uses the alias count.
- JavaScript SDK
- Python SDK
- Refine
- REST API
await database
.from('tasks')
.aggregate('count(*)')
.first();
(
client.database
.from_("tasks")
.aggregate("count(*)")
.first()
)
useList({
resource: 'tasks',
pagination: {mode: 'off'},
meta: {aggregate: ['count(*)']},
});
After the query succeeds, result.data[0].count is the task count.
result.total is the number of summary rows, not the number of tasks.
/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/Headers
AuthorizationApi-Key $TARUVI_API_KEY
Query parameters
_aggregatecount(*)
View cURL
curl -G "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
--data-urlencode '_aggregate=count(*)'
200Read the count from data[0].count.
Group records#
Group by done to produce one row for completed tasks and another for
incomplete tasks.
- JavaScript SDK
- Python SDK
- Refine
- REST API
await database
.from('tasks')
.aggregate('count(*)')
.groupBy('done')
.sort('count', 'desc')
.sort('done', 'asc')
.execute();
(
client.database
.from_("tasks")
.aggregate("count(*)")
.group_by("done")
.sort("count", "desc")
.sort("done", "asc")
.execute()
)
useList({
resource: 'tasks',
sorters: [
{field: 'count', order: 'desc'},
{field: 'done', order: 'asc'},
],
pagination: {mode: 'off'},
meta: {aggregate: ['count(*)'], groupBy: ['done']},
});
/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/Headers
AuthorizationApi-Key $TARUVI_API_KEY
Query parameters
_aggregatecount(*)_group_bydoneordering-count,done
View cURL
curl -G "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
--data-urlencode '_aggregate=count(*)' \
--data-urlencode '_group_by=done' \
--data-urlencode 'ordering=-count,done'
200Returns one summary row for each distinct done value.
A representative data value is:
[
{"done": false, "count": 12},
{"done": true, "count": 8}
]
Pass several fields to the SDK method, or use a comma-separated REST value to group by more than one field.
Calculate several summaries#
One request can include several aggregate expressions. This example groups projects by status and calculates the count, average, minimum, and maximum priority.
- JavaScript SDK
- Python SDK
- Refine
- REST API
await database
.from('projects')
.aggregate(
'count(*)',
'avg(priority)',
'min(priority)',
'max(priority)',
)
.groupBy('status')
.sort('status', 'asc')
.execute();
(
client.database
.from_("projects")
.aggregate(
"count(*)",
"avg(priority)",
"min(priority)",
"max(priority)",
)
.group_by("status")
.sort("status", "asc")
.execute()
)
useList({
resource: 'projects',
sorters: [{field: 'status', order: 'asc'}],
pagination: {mode: 'off'},
meta: {
aggregate: ['count(*)', 'avg(priority)', 'min(priority)', 'max(priority)'],
groupBy: ['status'],
},
});
/api/apps/$TARUVI_APP_SLUG/datatables/projects/data/Headers
AuthorizationApi-Key $TARUVI_API_KEY
Query parameters
_aggregatecount(*),avg(priority),min(priority),max(priority)_group_bystatusorderingstatus
View cURL
curl -G "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/datatables/projects/data/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
--data-urlencode '_aggregate=count(*),avg(priority),min(priority),max(priority)' \
--data-urlencode '_group_by=status' \
--data-urlencode 'ordering=status'
200Returns one summary row for each project status.
Filter source records#
Ordinary filters on the root table run before aggregation. This example counts only incomplete tasks.
- JavaScript SDK
- Python SDK
- Refine
- REST API
await database
.from('tasks')
.filters('done', 'eq', false)
.aggregate('count(*)')
.execute();
(
client.database
.from_("tasks")
.filter("done", "eq", False)
.aggregate("count(*)")
.execute()
)
useList({
resource: 'tasks',
filters: [{field: 'done', operator: 'eq', value: false}],
pagination: {mode: 'off'},
meta: {aggregate: ['count(*)']},
});
/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/Headers
AuthorizationApi-Key $TARUVI_API_KEY
Query parameters
donefalse_aggregatecount(*)
View cURL
curl -G "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
--data-urlencode 'done=false' \
--data-urlencode '_aggregate=count(*)'
200Returns a count summary for tasks where done is false.
Keep an aggregate request focused on one table. Query related tables separately when a summary depends on them. Vector and hybrid search are also separate query modes; keep those queries separate from aggregation.
Filter grouped results#
Use a having condition after grouping. Conditions refer to generated
aggregate aliases; count__gte=10 keeps groups with at least ten records.
- JavaScript SDK
- Python SDK
- Refine
- REST API
await database
.from('tasks')
.aggregate('count(*)')
.groupBy('done')
.having('count__gte=10')
.sort('count', 'desc')
.sort('done', 'asc')
.execute();
(
client.database
.from_("tasks")
.aggregate("count(*)")
.group_by("done")
.having("count__gte=10")
.sort("count", "desc")
.sort("done", "asc")
.execute()
)
useList({
resource: 'tasks',
sorters: [
{field: 'count', order: 'desc'},
{field: 'done', order: 'asc'},
],
pagination: {mode: 'off'},
meta: {
aggregate: ['count(*)'],
groupBy: ['done'],
having: [{field: 'count', operator: 'gte', value: 10}],
},
});
/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/Headers
AuthorizationApi-Key $TARUVI_API_KEY
Query parameters
_aggregatecount(*)_group_bydone_havingcount__gte=10ordering-count,done
View cURL
curl -G "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/datatables/tasks/data/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
--data-urlencode '_aggregate=count(*)' \
--data-urlencode '_group_by=done' \
--data-urlencode '_having=count__gte=10' \
--data-urlencode 'ordering=-count,done'
200Returns only completion groups containing at least ten tasks.
Aggregate functions and aliases#
| Expression | Default alias | Result |
|---|---|---|
count(*) | count | Number of matching records |
count(field) | count_field | Number of non-null values |
sum(field) | sum_field | Sum of numeric values |
avg(field) | avg_field | Average of numeric values |
min(field) | min_field | Smallest value |
max(field) | max_field | Largest value |
array_agg(field) | array_agg_field | Values collected in an array |
json_agg(field) | json_agg_field | Values collected as JSON |
stddev(field) | stddev_field | Standard deviation |
variance(field) | variance_field | Variance |
Sort fields can reference group fields or aggregate aliases. A having condition
can reference only an aggregate alias, such as count or sum_amount. Use
root-table filters and carefully chosen group fields when a query can produce
many summary rows.