πŸŽ‰ 75% of content is free forever β€” Unlock Premium from $10/mo β†’
CW
Search courses…
πŸ’Ό Servicesℹ️ Aboutβœ‰οΈ ContactView Pricing Plansfrom $10

SQL Views

SQL Database ObjectsViews🟒 Free Lesson

Advertisement

SQL Database Objects

SQL Views

Save a query as a virtual table β€” simplify complex joins and secure sensitive data.

  • Simplify β€” Hide complex joins and subqueries behind a clean interface
  • Secure β€” Restrict access to specific columns or rows
  • Standardize β€” Provide a consistent API even when the underlying schema changes A view is a named query stored in the database β€” not a new copy of the data.

What Is a View?

DfView

A view is a stored SELECT statement that behaves like a virtual table. When you query a view, the database executes the underlying query and returns the results. Views do not store data β€” they execute their query on demand (unless materialized).

Applicationv_employee_dir (View)Underlying Query Executesemployeesid, name, dept_idsalary, hire_datedepartmentsid, namelocationView = named query stored in database (no data copied)
-- Create a view that joins employees with departments
CREATE VIEW v_employee_directory AS
SELECT
    e.employee_id,
    e.first_name,
    e.last_name,
    e.email,
    d.department_name,
    e.salary
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
-- Query the view like a regular table
SELECT * FROM v_employee_directory
WHERE department_name = 'Engineering';

Simple vs Complex Views

DfSimple View

A simple view is derived from a single table and does not use aggregate functions. Most databases allow INSERT, UPDATE, and DELETE operations on simple views.

DfComplex View

A complex view is constructed from multiple tables, uses JOINs, GROUP BY, or aggregate functions. Most databases make complex views read-only.

CharacteristicSimple ViewComplex View
Source tablesSingle tableMultiple tables
JOINsNoYes
GROUP BYNoYes
Aggregate functionsNoYes
DML (INSERT/UPDATE/DELETE)Usually yesUsually no
WITH CHECK OPTIONSupportedLimited

Creating Views

Basic View

CREATE VIEW v_active_employees AS
SELECT
    employee_id,
    first_name,
    last_name,
    email,
    department_id
FROM employees
WHERE status = 'Active';

View with JOIN

CREATE VIEW v_employee_compensation AS
SELECT
    e.employee_id,
    e.first_name || ' ' || e.last_name AS full_name,
    e.salary,
    COALESCE(b.bonus, 0) AS bonus,
    e.salary + COALESCE(b.bonus, 0) AS total_compensation
FROM employees e
LEFT JOIN bonuses b ON e.employee_id = b.employee_id;

View with Aggregation

CREATE VIEW v_department_summary AS
SELECT
    d.department_name,
    COUNT(e.employee_id) AS employee_count,
    AVG(e.salary) AS avg_salary,
    MAX(e.salary) AS max_salary,
    MIN(e.salary) AS min_salary
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_name;

View with Subquery

CREATE VIEW v_above_average_salary AS
SELECT
    employee_id,
    first_name,
    last_name,
    salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

Modifying and Dropping Views

-- Replace an existing view
CREATE OR REPLACE VIEW v_employee_directory AS
SELECT
    e.employee_id,
    e.first_name,
    e.last_name,
    e.email,
    e.phone,
    d.department_name,
    e.salary,
    e.hire_date
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
-- Drop a view
DROP VIEW IF EXISTS v_employee_directory;
-- Rename a view (PostgreSQL)
ALTER VIEW v_employee_directory RENAME TO v_employee_info;

Updatable Views

DfUpdatable View

A view is updatable when the database can map DML operations back to the underlying base table. Simple views on a single table are generally updatable. Views with JOINs, DISTINCT, GROUP BY, or aggregates are typically read-only.

-- Updatable view
CREATE VIEW v_senior_employees AS
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE salary >= 80000;

-- This UPDATE flows through to the base table
UPDATE v_senior_employees
SET salary = salary * 1.10
WHERE employee_id = 101;
-- WITH CHECK OPTION prevents inserting rows that violate the view's WHERE clause
CREATE VIEW v_active_engineers AS
SELECT employee_id, first_name, last_name, department_id
FROM employees
WHERE department_id = 5 AND status = 'Active'
WITH CHECK OPTION;

-- This INSERT is rejected β€” violates the WHERE clause
INSERT INTO v_active_engineers (first_name, last_name, department_id)
VALUES ('Jane', 'Doe', 3);  -- ERROR: department_id is not 5

Materialized Views

DfMaterialized View

A materialized view stores the result of the query physically on disk. It must be refreshed explicitly or on a schedule to stay current. Materialized views are ideal for expensive aggregations and reporting queries.

-- PostgreSQL: Create a materialized view
CREATE MATERIALIZED VIEW mv_sales_summary AS
SELECT
    product_id,
    DATE_TRUNC('month', sale_date) AS month,
    SUM(amount) AS total_sales,
    COUNT(*) AS transaction_count
FROM sales
GROUP BY product_id, DATE_TRUNC('month', sale_date);
-- Refresh the materialized view
REFRESH MATERIALIZED VIEW mv_sales_summary;
-- Concurrent refresh (PostgreSQL only β€” allows reads during refresh)
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_sales_summary;
FeatureRegular ViewMaterialized View
Data storageNo (virtual)Yes (physical)
Query performanceExecutes on demandPre-computed, instant
Data freshnessAlways currentStale until refreshed
Refresh neededNoYes
Storage costNoneDisk space required
DML operationsSometimesRarely

Views for Security

-- Hide sensitive salary data
CREATE VIEW v_public_employee_info AS
SELECT
    employee_id,
    first_name,
    last_name,
    email,
    department_id
FROM employees;

-- Grant access only to the view, not the base table
GRANT SELECT ON v_public_employee_info TO public_user;
REVOKE SELECT ON employees FROM public_user;
-- Row-level security via views
CREATE VIEW v_my_team AS
SELECT *
FROM employees
WHERE manager_id = CURRENT_USER_ID();

Performance Considerations

ScenarioRecommendation
Simple column selection from a single tableUse a view for abstraction, not performance
Complex JOIN across many tablesView helps readability; optimize the underlying query
Expensive aggregation run frequentlyUse a materialized view
Dashboard with fixed time rangesMaterialized view refreshed nightly
Real-time data requirementsRegular view (not materialized)

Views do not improve performance on their own β€” they execute the underlying query each time. For expensive, frequently-run queries, use materialized views instead.

Common Pitfalls

PitfallProblemSolution
Nested views (view of a view)Hard to debug, performance degradesKeep views shallow β€” one level deep
Overusing views for everythingCreates a maze of dependenciesUse views selectively for complex joins and security
Forgetting to refresh materialized viewsStale data served to usersSchedule refreshes or use triggers
Updatable views with complex joinsDML operations fail silentlyTest DML on views before relying on them
Naming inconsistencyConfusion between tables and viewsPrefix views with v_ or vw_

Key Takeaways

  1. A view is a stored SELECT statement β€” a virtual table that executes its query on demand
  2. Simple views on single tables are often updatable; complex views with JOINs are usually read-only
  3. Materialized views store results physically and must be refreshed β€” ideal for expensive aggregations
  4. Views are powerful for security β€” they can hide columns, rows, or sensitive data from users
  5. Views do not improve performance by themselves; use materialized views for pre-computed results
⭐

Premium Content

SQL Views

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
πŸ’ΌInterview Prep
πŸ“œCertificates
🀝Community Access

Already a member? Log in

Need Expert SQL Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement