# Dataset saved views
A saved view is a named, read-only SQL query over a project's datasets and
other views. It is a **logical definition, not materialized data**: every
execution runs against the current state, so a view automatically reflects new
pushes.
Views are the UI's way to combine multiple datasets. A single-dataset query can
only reference `dataset`; a view can join any datasets in the project.
## Create a view
In **Datasets → Views**, choose **New view** and provide:
|
Field
|
Rules
|
|
Name
|
Starts with a letter; letters, digits, and dashes; up to 255 characters. Must be unique case-insensitively among the project's dataset tables and views.
|
|
Description
|
Optional, up to 1024 characters.
|
|
SQL
|
One read-only
SELECT
.
|
Example — severity counts across a findings dataset:
```sql
SELECT severity, COUNT(*) AS findings
FROM findings
GROUP BY severity
```
Example — join subdomains with live services:
```sql
SELECT s.host, w.status_code, w.title
FROM subdomains AS s
JOIN "web-services" AS w ON s.host = w.host
WHERE w.status_code BETWEEN 200 AND 299
```
Quote dataset and view names that contain dashes. See
[SQL reference](/datasets/sql) for the query policy and result limits.
## SQL policy and references
Views use the same read-only SQL policy as direct queries:
- One read-only `SELECT` (or a `WITH ... SELECT` CTE — views are validated with
the SQL parser, so they are the place to use CTEs).
- No DDL/DML, `COPY`, `ATTACH`, file scans, catalog tables, or table functions.
- Every referenced relation must be a dataset or an existing view in the same
project.
Unlike a single-dataset query, a view may **reference other views**, as long as
the dependency graph is acyclic. Creating or updating a view runs cycle
detection across the project; a cycle fails with an error that names the cycle.
## Validity
Each view has `valid` and `invalid_reason` fields.
A view becomes invalid when:
- a dataset or view it references is deleted (for a deleted view this happens
immediately; for a dataset, on the next execution);
- its stored SQL no longer satisfies the current SQL policy; or
- execution fails because a column or type no longer exists.
Executing an invalid view returns an error and records the reason. Saving the
view again (after fixing the SQL or restoring the reference) resets it to valid.
The Views list marks invalid views with a red status dot.
Deleting a view also invalidates views that depend on it.
## Execute a view
|
Property
|
Value
|
|
Scope
|
Current state only; no history mode
|
|
Filters
|
None; put predicates in the view SQL
|
|
Time range
|
None; filter on
__ingested_at
in the SQL if needed
|
|
Page size
|
Default 100, maximum 10,000
|
|
Pagination
|
Opaque cursor; ordered by the first column ascending
|
Execution wraps the view as `SELECT * FROM ""` and applies the same
pagination as direct SQL. If you need a particular order, make the sort key the
first projected column.
The Hub UI's **Run view** executes the first page and displays the rows. Use the
API (`ExecuteDatasetView`) to page through larger results.
## Update and delete
- Editing a view's name, description, or SQL is available through the API
(`UpdateDatasetView`); the Hub UI currently supports create, run, and delete.
- Deleting a view is permanent. Dependent views become invalid.
- Views are limited to 100 per project.
## Examples
### Findings by severity count
```sql
SELECT COUNT(*) AS findings, severity
FROM findings
GROUP BY severity
```
The page is sorted by the first column (`findings`) ascending, so the largest
groups appear last. Sort the returned rows client-side if you need descending.
### Live services
```sql
SELECT host, status_code, title
FROM "web-services"
WHERE status_code BETWEEN 200 AND 399
```
### Unresolved subdomains
```sql
SELECT host
FROM subdomains
WHERE NOT resolved
```
### Aggregated rollup
```sql
WITH counts AS (
SELECT program, COUNT(*) AS findings
FROM findings
GROUP BY program
)
SELECT program, findings
FROM counts
WHERE findings > 0
```
## Errors
|
Error
|
Cause
|
View reference unknown dataset or view
|
The SQL references a name that is not a dataset or view in the project.
|
View dependency cycle detected
|
The new or updated view would create a cycle.
|
View '' is invalid
|
Execution found the view no longer satisfies the policy.
|
View '' cannot be evaluated
|
A column, type, or referenced relation changed.
|
Too many requests
|
The per-user concurrency or rate limit was exceeded.
|
## Related
- [SQL reference](/datasets/sql) — the full query language and limits.
- [API and CLI](/datasets/api-cli) — `DatasetViewService` requests.
- [Overview](/datasets/overview) — current state vs history.