# Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,

`POST /datanotes/operations/select_rows/` (operation `select_rows`)

Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,
`system.information_schema.<catalogs|schemata|tables|columns|views|check_constraints>`, or
`base:<name>` — every table that extends that base (e.g. `base:record`: all event-like tables),
on the base's columns, each row tagged `_source` with its table.
- `where`: as in update_rows; relative dates `"{today}"`, `"{today-7d}"`, `"{now-24h}"` (on a date column a date-time
  counts by its day); file columns
  `file_name`, `file_link`, `file_modified`, `file_backlink_count`.
- `columns`, `order_by` (`-col` descending), `limit` (default 100, max 1000), `offset`,
  `expand` (inline linked rows' frontmatter), `include_body` (the note body as `body`).
- `join`: `{"table", "on": {"date(occurred_at)+1": "date(timestamp)"}, "as", "type": "inner"|"left",
  "columns", "where"}` — matches attached under `as`.
- `group_by` (column, `path` or `date(col)±n`; a list column counts once per item) + `aggregates`
  `{"n": "count", "kcal": "sum:meal.kcal"}` (count, count:col, sum, avg, min, max).
- `this_note`: vault path of the note the result is for: `{this.*}` tokens in a view's query
  and in `where` read it (`{this.date}`, `{this.link}`, `{this.name}`, `{this.path}`); without
  it (or a front matter key the note lacks) a token stays as written and matches no row, whatever the
  operator (`within` included).
- Ordered enums compare by position. Time travel: `version` (of one table) or `timestamp`. With
  `timestamp` a join, a view, a union or `base:<name>` reads every table in it as of that time
  (`versions`: the version read of each); a table that did not exist then adds no rows to a union or
  base. `version` is refused where several tables are read; information_schema has no history.
  Views and bases keep today's definition, and links followed by `where` (`project.kind`, `within`)
  or `expand` read the linked rows as they are now.

## Request body

`application/json`, required

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `table` | `string` | yes |  |  |
| `columns` | `string[] \| null` | no | `null` |  |
| `where` | `object \| null` | no | `null` |  |
| `order_by` | `string \| string[] \| null` | no | `null` |  |
| `limit` | `integer \| null` | no | `null` |  |
| `offset` | `integer \| null` | no | `null` |  |
| `expand` | `string[] \| null` | no | `null` |  |
| `join` | `object \| null` | no | `null` |  |
| `group_by` | `string \| string[] \| null` | no | `null` |  |
| `aggregates` | `object \| null` | no | `null` |  |
| `include_body` | `boolean` | no | `false` |  |
| `version` | `integer \| null` | no | `null` |  |
| `timestamp` | `string \| null` | no | `null` |  |
| `this_note` | `string \| null` | no | `null` |  |

## Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | Done. | `object` (application/json) |
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
| 500 | Unexpected error. | `Error` (application/json) |

The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
