Views: Saved Queries
Create views that store a query (not data), use them like tables, and know when to choose a view over a table or CTE.
Five analysts all need "total runs per team". If each one writes their own GROUP BY, someone will get it wrong. A view lets you define that logic once in the database, and everyone queries it like a table.
Definition
A view is a virtual table defined by a stored
SELECTquery. The database saves only the query definition, not the data. Every time someone selects from the view, the database runs the saved query against the underlying (base) tables and returns the current rows.
- Virtual table — it has columns and rows and you query it with
SELECT … FROM view_name, but it does not physically hold rows. - Stored query — the
SELECTtext is saved permanently in the database (until youDROP VIEW). - Always current — because it runs live, it always reflects the latest data in the base tables.
The flow: Tables (physical data on disk) → View (a saved SELECT) → Users / reports (analysts, BI tools, apps) query the view.
Views vs tables
| Table | View | |
|---|---|---|
| Stores data? | YES — physically on disk | NO — only the SELECT query |
| Disk space | Yes | Almost none |
| Data freshness | As last loaded / updated | Always current (runs live) |
| Speed | Fast to read | Runs the query every time |
| Created with | CREATE TABLE | CREATE VIEW … AS SELECT |
Syntax
sql
CREATE VIEW view_name AS
SELECT column_list
FROM table_name
WHERE condition;
ALTER VIEW view_name AS -- change the definition
SELECT ...;
DROP VIEW view_name; -- remove the view (base tables are untouched)| Keyword | Meaning |
|---|---|
CREATE VIEW name AS | saves the SELECT under a name |
ALTER VIEW | replaces the saved SELECT (SQL Server; CREATE OR ALTER VIEW in 2016 SP1+) |
DROP VIEW | deletes the view definition only — no data is lost |
Tip: Name views with a
v_prefix (v_team_totals) so everyone knows it is a view, not a table.
Example — define logic once
sql
CREATE VIEW v_team_totals AS
SELECT
team,
SUM(runs) AS total_runs,
COUNT(*) AS players
FROM players
GROUP BY team;Then use it like a table:
sql
SELECT * FROM v_team_totals;| team | total_runs | players |
|---|---|---|
| CSK | 350 | 1 |
| DC | 700 | 1 |
| MI | 520 | 2 |
| RCB | 750 | 1 |
| RR | 850 | 1 |
sql
SELECT * FROM v_team_totals WHERE total_runs >= 700;| team | total_runs | players |
|---|---|---|
| DC | 700 | 1 |
| RCB | 750 | 1 |
| RR | 850 | 1 |
Change the view once → every report that uses it is updated.
Example — a view is always current
sql
UPDATE players SET runs = runs + 400 WHERE name = 'MS Dhoni'; -- 350 → 750
SELECT * FROM v_team_totals WHERE total_runs >= 700;| team | total_runs | players |
|---|---|---|
| CSK | 750 | 1 |
| DC | 700 | 1 |
| RCB | 750 | 1 |
| RR | 850 | 1 |
CSK appears now — nobody refreshed the view; it simply re-ran its query on the new data.
Why use views? Four classic reasons
| Reason | Example |
|---|---|
| Hide complexity | A 40-line join becomes SELECT * FROM v_report |
| Security | A view shows name and team but hides salary / contract columns; users get permission on the view, not the table |
| Flexibility | Change the logic in ONE place (ALTER VIEW) — all users see it |
| Virtual data marts | A ready-made slice for one team or topic, e.g. v_rcb_players |
sql
CREATE VIEW v_report AS
SELECT p.name, t.team_name, t.city, p.runs
FROM players AS p
INNER JOIN teams AS t
ON p.team = t.team;SELECT * FROM v_report ORDER BY runs DESC;
| name | team_name | city | runs |
|---|---|---|---|
| Jos Buttler | Rajasthan Royals | Jaipur | 850 |
| Virat Kohli | Royal Challengers Bengaluru | Bengaluru | 750 |
| David Warner | Delhi Capitals | Delhi | 700 |
| Rohit Sharma | Mumbai Indians | Mumbai | 500 |
| MS Dhoni | Chennai Super Kings | Chennai | 350 |
| Jasprit Bumrah | Mumbai Indians | Mumbai | 20 |
Views vs CTEs
Both hide complexity — but their lifetime differs.
| CTE | View | |
|---|---|---|
| Lifetime | ONE query only | Stored in the database until dropped |
| Reusable? | No — redefine it each time | Yes — by any query or user |
| Created with | WITH name AS (…) | CREATE VIEW name AS … |
| Permissions | None | Can be granted / restricted |
| Best for | Step-by-step logic inside one query | Shared business logic |
Rules and common mistakes
- ❌
ORDER BYinside a view → not allowed in SQL Server (unless withTOP). ✅ sort when you query the view. - ❌ Expecting a view to make a slow query fast → a normal view re-runs its query every time. ✅ use an indexed view (SQL Server's materialized view) or a CTAS table for speed.
- ❌ Parameters in a view (
WHERE team = @team) → views cannot take parameters. ✅ filter when you query it, or use a stored procedure / table-valued function. - ❌ In SSMS,
CREATE VIEWmixed with other statements → error "CREATE VIEW must be the only statement in the batch". ✅ separate batches withGO. - ❌ Dropping or renaming a column the view uses → the view breaks. ✅
WITH SCHEMABINDINGprevents such changes to the base table. - Views over a single table can sometimes be updated (
UPDATE v_rcb_players …changesplayers).WITH CHECK OPTIONstops inserts/updates that would fall outside the view'sWHERE.
SQL Server vs MySQL / PostgreSQL
| Task | SQL Server | MySQL / PostgreSQL |
|---|---|---|
| Change a view | ALTER VIEW or CREATE OR ALTER VIEW | CREATE OR REPLACE VIEW |
| Stored-result view | Indexed view | PostgreSQL: CREATE MATERIALIZED VIEW |
Interview tip
Q: Does a view store data? No. A normal view stores only its SELECT definition; the data stays in the base tables and the query runs each time. (The exception is an indexed / materialized view, which physically stores the result.)
Key points to remember
- A view is a virtual table defined by a stored SELECT — it saves the query, not the data.
- Querying a view runs its SELECT live, so the result is always current.
- Create with CREATE VIEW name AS SELECT …; change with ALTER VIEW; remove with DROP VIEW (data is not affected).
- Four reasons to use views: hide complexity, security (hide columns), flexibility (change logic in one place), virtual data marts.
- A CTE lives for one query; a view is stored in the database and reusable by anyone with permission.
- Views cannot take parameters and cannot contain ORDER BY (without TOP) in SQL Server.
- A normal view does not speed queries up; indexed / materialized views store results.
Try it yourself
Create and use v_team_totals
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
A view is always current
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Hide a join behind v_report
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Practice: a data-mart view for MI
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Revision Flashcards
Tap a card to flip it and see the answer.
