Query
The query directive saves a named query in your ledger, the same way Beancount and Fava do. Zhang lists saved
queries in the Saved menu of the Query page, so you can run them again without retyping them (see
Saved queries). The query itself is written in Zhang’s
query language.
Syntax
Section titled “Syntax”YYYY-MM-DD [HH:MM[:SS]] query "<Name>" "<Query>"| Part | Required | Description |
|---|---|---|
| Date and time | yes | The date of the query. It orders the list and tells queries with the same name apart. |
"<Name>" |
yes | The name shown in the Saved menu. A single word can be written without quotes. |
"<Query>" |
yes | The query text, in double quotes. It can span several lines. |
Metadata lines can follow the directive.
Examples
Section titled “Examples”2024-01-01 query "food by payee" "SELECT payee, sum(position) WHERE account ~ '^Expenses:Food' GROUP BY payee"
2024-02-01 query "monthly food" " SELECT year, month, sum(position) WHERE account ~ '^Expenses:Food' GROUP BY year, month" owner: "alice"Escaping
Section titled “Escaping”The query text is a quoted string, like any other string in the ledger file, so a backslash in it can start an escape sequence:
-
\"is a double quote and\\is a backslash. To use a double quote in the query, write\", or use single quotes for the strings inside the query, as in the examples on this page. -
\n,\t,\r,\b,\f,\/and\uXXXXare read as in JSON. The escapes that older versions of Zhang wrote are still read as the character they stand for:\$,\`,\a,\v,\eand\u{...}, such as\u{a0}. -
A backslash followed by any other character is kept as written. So the regular expression
\d+can be written as it is:2024-01-01 query "numbered" "SELECT narration WHERE narration ~ '\d+'" -
Writing the backslash twice, as in
'\\d+', also works and reads the same. Write it twice when the backslash comes before one of the characters listed above. In a regular expression,'\\b'is a word boundary, but'\b'is read as a backspace character;'\\$'matches a dollar sign, but'\$'is read as$, the end of the text.
A malformed \u escape, such as \uZZZZ, is an error that stops the ledger from loading. The error gives the line
and column of the escape.
Behavior
Section titled “Behavior”- Saved queries are not checked when the ledger is loaded. A query that does not compile, for example one written for a feature Zhang does not support yet, is still saved and never makes the ledger report an error. The Saved menu and the HTTP API say whether each query compiles.
- Every
querydirective is kept, including ones that share a name. Queries are listed in ledger order: by date, then in the order they appear in your files.
HTTP API
Section titled “HTTP API”GET /api/query/saved lists the saved queries:
{ "data": [ { "name": "food by payee", "query": "SELECT payee, sum(position) WHERE account ~ '^Expenses:Food' GROUP BY payee", "date": "2024-01-01", "valid": true, "error": null } ]}valid tells whether the query compiles with the current query engine. When it does not, error holds the reason,
with the line and column when they are known. Run a saved query by sending its query text to POST /api/query.
Errors
Section titled “Errors”A query directive produces no ledger error.
Beancount compatibility
Section titled “Beancount compatibility”The same syntax works in Beancount files (.bean), so ledgers written for Fava keep their saved queries. Zhang reads
their strings with the escaping rules above. Beancount itself drops a backslash that does not start an escape it
knows, so it reads '\d+' as 'd+'. It has no \uXXXX, \a, \v or \e escape either, so it reads \u00e9 as
u00e9 where Zhang reads é. If you also use the ledger with Beancount or Fava, write each backslash twice, as in
'\\d+'. That form reads the same in both.
For how Zhang’s query language differs from Beancount’s, see Differences from BQL and beanquery.
Related
Section titled “Related”- Querying: the Query page and common queries.
- Query language: the full reference.
