Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/sql/materialized_views.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ DROP MATERIALIZED VIEW IF EXISTS orders_with_customers_mv;
| **`RIGHT JOIN` / `FULL OUTER JOIN`** | Not supported (see below). Use `LEFT JOIN` with swapped table order. |
| **Aggregates need a `GROUP BY`** | A view that selects an aggregate — a window function, a percentile or a standard deviation included — without a `GROUP BY`, or whose `GROUP BY` reaches none of the tables it reads (a `CROSS JOIN`ed table, or an alias of a table joined more than once that the view does not read: only one alias of such a table is read), is refused at creation: a materialized view computes aggregates per `GROUP BY` group, and without one it would store the source rows and none of the aggregates. The refusal names each aggregate the view would not store: compute it with a query instead. Known limitation: an aggregate nested inside a function or an expression, such as `ROUND(AVG(amount), 2)` or `SUM(amount) / COUNT(*)`, is not detected — the refusal does not name it, and does not refuse a view whose only aggregates are nested this way. |
| **Aggregates of an expression** | An aggregate whose operand is an expression rather than a column — `MAX(DATE_TRUNC(created_at, MONTH))`, `SUM(CAST(amount AS INT))`, `COUNT(UPPER(name))` — is refused at creation: a materialized view aggregates a column as it is stored, so it would compute `MAX(created_at)`, `SUM(amount)` and `COUNT(*)` in their place. A `CAST` over a column is refused too, whatever its type. Compute it with a query instead. |
| **One column per aggregate** | Two aggregates that would produce the same column name — typically unaliased, `COUNT(x), COUNT(DISTINCT x)` or `SUM(amount), MAX(amount)` — are refused at creation; give each its own alias (`COUNT(x) AS n, COUNT(DISTINCT x) AS n_distinct`). The refusal proposes aliases only for the aggregates the view would store under them, and names the others — for example a window function, a percentile, or an aggregate of a column in a single-table view without a computed column — to be computed with a query. A `COUNT(*)` is named, but neither aliased nor sent to a query. |
| **One column per aggregate** | Two aggregates that would produce the same column name — typically unaliased, `COUNT(x), COUNT(DISTINCT x)` or `SUM(amount), MAX(amount)` — are refused at creation; give each its own alias (`COUNT(x) AS n, COUNT(DISTINCT x) AS n_distinct`). The refusal proposes aliases only for the aggregates the view would store under them, and names the others — for example a window function, a percentile, or an aggregate of a column in a single-table view without a computed column — to be computed with a query. A `COUNT(*)` is one of the aggregates a view stores, so the refusal proposes an alias for it too. |
| **Quota limits** | Community: 1 view · Pro: 50 · Enterprise: unlimited |
| **Watcher dependency (ES license)** | Automatic enrich policy re-execution relies on Elasticsearch Watcher, which the free Basic license does not include. The view is still created and `REFRESH MATERIALIZED VIEW` still works (see below) |
| **Eventual consistency** | Data is eventually consistent based on refresh frequency and delay |
Expand Down
Loading