A view is a saved query you can select from as if it were a table.
SQL
CREATE VIEW book_details AS
SELECT
b.id,
b.title,
b.price,
a.name AS author_name,
c.name AS category_name
FROM books b
LEFT JOIN authors a ON a.id = b.author_id
LEFT JOIN categories c ON c.id = b.category_id;SQL
SELECT * FROM book_details WHERE price < 500;The view stores no data — it runs the underlying query every time.
Why views help
- Hide join complexity behind a simple name.
- Present a stable interface while the tables underneath change.
- Restrict access: grant
SELECTon a view exposing only safe columns.
SQL
CREATE VIEW public_users AS
SELECT id, full_name, created_at FROM users WHERE is_active = true;
GRANT SELECT ON public_users TO reporting_role;Replacing and dropping
SQL
CREATE OR REPLACE VIEW book_details AS SELECT ...;
DROP VIEW IF EXISTS book_details;CREATE OR REPLACE cannot change existing column names or types — drop
and recreate for that.
Updatable views
A simple view over one table, with no aggregates or DISTINCT, accepts
INSERT/UPDATE/DELETE directly. Anything more complex needs an
INSTEAD OF trigger.
SQL
CREATE VIEW cheap_books AS
SELECT * FROM books WHERE price < 300
WITH CHECK OPTION;WITH CHECK OPTION stops you inserting a row through the view that the
view itself would not show.
Materialised views
These do store the result — a cached snapshot for expensive queries:
SQL
CREATE MATERIALIZED VIEW sales_summary AS
SELECT
date_trunc('month', created_at) AS month,
COUNT(*) AS orders,
SUM(total) AS revenue
FROM orders
GROUP BY 1;
CREATE UNIQUE INDEX ON sales_summary (month);The data is frozen until you refresh it:
SQL
REFRESH MATERIALIZED VIEW sales_summary;
-- no read lock, but needs a unique index
REFRESH MATERIALIZED VIEW CONCURRENTLY sales_summary;Use materialised views for dashboards and reports where a few minutes of staleness is acceptable and the query is too slow to run per page load.
View vs materialised view
| View | Materialised view | |
|---|---|---|
| Stores data | no | yes |
| Always current | yes | only after refresh |
| Query cost | full cost every time | cheap read |
| Can be indexed | no | yes |