> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lancedb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a view

> Define a derived dataset as a saved query, with no storage or refresh of its own.

**Applies to:** Embedded ❌, Enterprise ✅

A view is the lightest way to derive a feature-engineered dataset: it stores
a **query**, not rows, so there is nothing to refresh and nothing that can
fall out of date. Reach for one before
[a computed column](https://docs.lancedb.com/feature-engineering/add-computed-column.md) or
[a materialized view](https://docs.lancedb.com/feature-engineering/materialized-views.md) when the
underlying query is cheap enough to simply re-run on every read.

## Define a view

A view over a products table, selecting and deriving a few columns:

```sql SQL icon="database" theme={"theme":{"light":"vitesse-light","dark":"catppuccin-mocha"}}
CREATE VIEW "discounted_products" AS
SELECT id, name, price, price * 0.9 AS sale_price
FROM "products"
WHERE in_stock = true
```

The statement resolves the view's schema from the query at creation time.
Anything the [SQL dialect](https://docs.lancedb.com/sql/dql/functions.md) supports can define one: joins,
predicates, aggregates, window functions -- the same expressiveness as
[a computed column's](https://docs.lancedb.com/feature-engineering/add-computed-column.md#expressions)
SQL expression, just over a whole derived table instead of one column.

## Read it like a table

```sql SQL icon="database" theme={"theme":{"light":"vitesse-light","dark":"catppuccin-mocha"}}
SELECT * FROM "discounted_products" WHERE sale_price < 20
```

Every read runs the saved query against current data, so `sale_price`
reflects whatever `price` is right now -- there is no staleness window to
reason about, unlike a materialized view between refreshes. A predicate
applied when reading the view composes with the query inside it, rather than
filtering the view's output afterward, so a selective filter does not pay
for rows the view would have produced and then discarded.

## When to use a view instead

| | View | Computed column / materialized view |
| - | - | - |
| Stores | the query | derived values |
| Freshness | always current | as of the last refresh |
| Read cost | the full query, every read | a column or table scan |
| Write cost | none | a refresh |

Reach for a view when the query is cheap, or when reading a stale value would
be wrong for the workload. Reach for a computed column or a materialized view
when the query is expensive and the data changes less often than it is read.
See [View](https://docs.lancedb.com/sql/ddl/view.md#choosing) for the full SQL reference comparison,
including the separate privileges each one needs.

## What to read next

> [card] [View](https://docs.lancedb.com/sql/ddl/view.md)
>
> CREATE VIEW, DROP VIEW, and listing views alongside tables.

> [card] [Create a materialized view](https://docs.lancedb.com/feature-engineering/materialized-views.md)
>
> The stored-rows counterpart, and when a refresh is worth paying for.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.