Preparing your learning space...
A view is a stored SELECT query that acts like a virtual table. It pulls data from real tables every time you query it — no data is stored in the view itself. Useful for simplifying complex joins, restricting column access, and reusing query logic.
A view is a saved SQL query you can query like a real table. Every time you access it, MySQL runs the underlying query against the base tables.
Why use views:
CREATE VIEW view_name AS
SELECT columns
FROM tables
WHERE conditions;
CREATE VIEW active_customers AS
SELECT id, name, email, signup_date
FROM customers
WHERE status = 'active';
Query the view like a table:
SELECT * FROM active_customers;
SELECT name, email FROM active_customers WHERE signup_date > '2025-01-01';
CREATE VIEW order_summary AS
SELECT
o.id AS order_id,
c.name AS customer_name,
p.name AS product_name,
oi.quantity,
oi.quantity * p.price AS total
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id;
Now a simple query replaces a four-table join:
SELECT * FROM order_summary WHERE customer_name = 'John Doe';
SHOW FULL TABLES WHERE Table_Type = 'VIEW';
See how a view is defined:
SHOW CREATE VIEW active_customers;
Replaces an existing view's definition, or creates it if it doesn't exist. No need to DROP first.
CREATE OR REPLACE VIEW view_name AS
new_select_query;
Current active_customers has id, name, email, signup_date. You need phone too:
CREATE OR REPLACE VIEW active_customers AS
SELECT id, name, email, phone, signup_date
FROM customers
WHERE status = 'active';
If the view exists — replaced. If not — created.
In MySQL,
ALTER VIEW view_name AS ...does the same thing.CREATE OR REPLACE VIEWis more widely used and portable.
"Update view" in MySQL can mean two different things. Both are covered below.
Changing what the view shows → use CREATE OR REPLACE VIEW (covered above).
Modifying actual table data by running UPDATE, INSERT, or DELETE on the view.
This only works on updatable views. A view is updatable when it:
GROUP BY, DISTINCT, HAVING, window functions, or aggregate functions (SUM, COUNT, AVG, etc.).SELECT list.UNION or UNION ALL.CREATE VIEW active_customers AS
SELECT id, name, email, status
FROM customers
WHERE status = 'active';
Update rows:
UPDATE active_customers
SET email = 'newemail@example.com'
WHERE id = 5;
Insert rows:
INSERT INTO active_customers (id, name, email, status)
VALUES (10, 'Jane Doe', 'jane@example.com', 'active');
Delete rows:
DELETE FROM active_customers WHERE id = 10;
CREATE VIEW customer_order_count AS
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;
GROUP BY + aggregate function → not updatable. UPDATE or INSERT on this view will fail.
When you insert or update through a view, MySQL lets you add rows that the view wouldn't show back. Example: an active_customers view only shows status = 'active'. You could INSERT a row with status = 'inactive' — it goes into the table but disappears from the view.
To prevent this:
CREATE VIEW active_customers AS
SELECT id, name, email, status
FROM customers
WHERE status = 'active'
WITH CHECK OPTION;
Now any INSERT or UPDATE that violates WHERE status = 'active' is rejected.
MySQL supports two levels:
WITH LOCAL CHECK OPTION -- checks only this view's WHERE clause
WITH CASCADED CHECK OPTION -- checks this view AND any views it's built on (default)
WITH CHECK OPTIONonly applies to modifications through the view. Direct table changes are unaffected.
Removes the view. Underlying tables and their data are untouched.
DROP VIEW [IF EXISTS] view_name;
DROP VIEW active_customers;
Drop multiple at once:
DROP VIEW IF EXISTS active_customers, order_summary, customer_order_count;
IF EXISTS prevents an error if a view doesn't exist.
Cascading views: If view B is built on view A, dropping A will break B. B still exists but errors when queried.
MySQL ignores ORDER BY in a view definition unless LIMIT is also used.
-- This ORDER BY is ignored
CREATE VIEW recent_users AS
SELECT * FROM users ORDER BY created_at DESC;
-- This will NOT return rows in any guaranteed order
SELECT * FROM recent_users;
-- Apply ORDER BY in the outer query instead
SELECT * FROM recent_users ORDER BY created_at DESC;
Views are not pre-computed or cached. Every query on a view runs the underlying SQL. They simplify your queries — they do not speed them up.
(MySQL does not support materialized views. For caching, look into query cache or application-level caching instead.)
If you alter or drop a base table that a view references, the view may break. Use CHECK TABLE view_name to verify a view's integrity.
Save your progress and earn XP for completing tutorials.
Keep learning
Technology
MySQL
Lesson group
Views
Progress
100% complete