SapixDBSapixDB/Docs
Home
Community · SaQL

Group-By Queries

Count how many records share each unique value of a field using "type": "group_by". Get a breakdown by plan, status, region, or any other categorical field in a single round-trip.

Query Shape

Send a POST to /v1/agents/:id/query with "type": "group_by" and the field to group by. The query counts records per unique value — it does not apply a numeric aggregate function.

SaQL — group_by query shape
POST /v1/agents/:id/query
Authorization: Bearer spx_root_YOUR_ROOT_KEY
Content-Type: application/json

{
  "type":  "group_by",
  "field": "plan",
  "limit": 50
}
FieldRequiredDescription
typeyesMust be "group_by".
fieldyesThe record field whose distinct values form the groups.
limitno (default 10)Maximum number of groups to return. Useful when the field has high cardinality.

Response Shape

The result is in groups — an array sorted by count descending. Each entry gives the field value and how many records carry that value. The top-level records array is empty.

JSON response
{
  "records": [],
  "groups": [
    { "value": "free",       "count": 142 },
    { "value": "starter",    "count": 38  },
    { "value": "pro",        "count": 21  },
    { "value": "enterprise", "count": 4   }
  ]
}
KeyTypeDescription
valuestring | number | nullThe distinct value of field for this bucket.
countintegerNumber of records with this value.

Examples

Count users per plan
curl -s -X POST http://localhost:7475/v1/agents/users/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer spx_root_YOUR_ROOT_KEY" \
  -d '{"type":"group_by","field":"plan","limit":20}'
Count orders per status
curl -s -X POST http://localhost:7475/v1/agents/orders/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer spx_root_YOUR_ROOT_KEY" \
  -d '{"type":"group_by","field":"status"}'
Python — top 10 regions by record count
import requests

resp = requests.post(
    "http://localhost:7475/v1/agents/events/query",
    json={"type": "group_by", "field": "region", "limit": 10},
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer spx_root_YOUR_ROOT_KEY",
    },
)
resp.raise_for_status()

for g in resp.json()["groups"]:
    print(f"{g['value']:<20} {g['count']:>6} records")
group_by counts; aggregate computes a numeric scalargroup_by returns counts per unique value. To compute a sum, average, min, or max across all records (not per group), use the aggregate query type. See Aggregate Functions. To count records matching a filter without grouping, use {"type":"count","filter":{...}}.