Skip to content
wannacode

Views

In short: A view is a query saved under a name that you use like a table, but it stores no data of its own.

Problem

The same calculation everywhere

How much is an order worth? There is no sum in orders. It is calculated from the order's rows:

SQLdatabase: shop

This calculation is needed for the daily report, for the customer statement, for the list of unpaid orders. Each time it is written again. If one day a delivery fee or a discount is added, it has to be fixed in ten places. And one of them will be forgotten.

The idea

CREATE VIEW

CREATE VIEW name AS SELECT … saves a query under a name. This is a view. After that the view is read like a table:

SQLdatabase: shop

The calculation is written once, in the view. The reports only say FROM order_totals.

The idea

Like a table

In SELECT a view is used like any table: with WHERE, ORDER BY, JOIN. In this field order_totals has already been made. Here are the new orders, with the customer and the value:

SQLdatabase: shop

The query is shorter and clearer: “the order, the customer, the value”. How the value is calculated is hidden in the view.

Try it

The big orders

The view order_totals is ready. Which orders are over 100 €? Show the number and the value.

SQLdatabase: shop

See it

A view holds no data

The customer of order 1 calls: they want 5 packs of white cheese, not 4. Run the query and look at both results:

SQLdatabase: shop

Before it is 31.60 €, after it is 39.50 €. Nobody touched the view. The view does not keep the values, only the query. Every read runs it again on the tables, so a view cannot go stale.

That is also why you cannot write into a view:

SQLdatabase: shop

The data is changed in the tables the view reads from.

More precisely, if you are curious

PostgreSQL also has CREATE MATERIALIZED VIEW: a view that keeps its result like a table. It is fast to read, but it goes stale and is refreshed with REFRESH MATERIALIZED VIEW. It is used for heavy reports that need not be accurate to the second. SQLite has no such view.

Try it

Sales by product

Make a view product_sales: for each product (product_id), how many pieces were ordered (sold), leaving out the rows of cancelled orders.

SQLdatabase: shop

The idea

DROP VIEW

A view is removed with DROP VIEW. DROP TABLE does not work:

SQLdatabase: shop
SQLdatabase: shop

The tables the view reads from are not touched. You remove only the saved query.

More precisely, if you are curious

To change a view in SQLite, you remove it with DROP VIEW and make it again with CREATE VIEW. PostgreSQL and MySQL have CREATE OR REPLACE VIEW, and SQLite does not:

SQLdatabase: shop

It works the other way too: a column that a view uses cannot be removed with DROP COLUMN (the previous lesson mentioned it).

Exercise

Two reports

1. The owner wants to send thank-you cards to the three customers who have ordered for the most money.

Using the view order_totals, show the customer's name and how much they ordered in total (spent), leaving out cancelled orders. Only the top three, from most to least.

SQLdatabase: shop

2. In the morning the warehouse looks at which orders are waiting.

Make a view open_orders with the order number, the customer's name and the order's value, only for new and paid orders (new, paid). Use order_totals.

SQLdatabase: shop

Test

Check yourself

1. What does the view order_totals keep?
2. How do you remove the view order_totals?
3. The quantity in a row of order 1 was changed with UPDATE. What do you have to do so that the value in order_totals is right?
4. Can you write a JOIN between a view and a table?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·