Skip to content

Aggregates

agg/aggregate aggregates a joined, incoming relation's column into the parent — necessary conditions:

{
  "relation": "properties", "schema": "hotel",
  "join": {
    "room_types": { "relation": "room_types", "schema": "hotel", "on": { "property_id": "id" } }
  },
  "select": {
    "name": "name",
    "room_type_count": ["agg", "count", [[".", "room_types", "id"]]],
    "budget_type_count": [
      "agg", "count", [[".", "room_types", "id"]],
      ["<", [".", "room_types", "base_price"], 150]
    ]
  }
}

Why: [".", "room_types", "id"] — not the bare string "room_types.id" — because a joined alias's column is always reached through the . operator (see Operators reference), never a dotted identifier string; there's no bare-string "alias.column" form in the JSON query grammar.

Filtering which rows get aggregated

The fourth, optional element of agg filters which rows get aggregated, independent of the query's own wherebudget_type_count above counts only room types priced under 150, while room_type_count still counts every room type, regardless of what the query's own where (if any) does at the properties level.

The function name

Both call and agg take a function name in the same form: either a bare, unqualified string (resolved via the search path) or an explicit {"schema": ..., "name": ...} object.

A computed field (see Computed fields) is never a write target — see Writing data back for what makes a column writable.