The practice database
Every example and exercise on this site uses one small database. It belongs to a made-up shop that sells groceries, stationery, electronics and things for the home. This page shows what is in it, so that you can check a table or column name while you write a query.
All the people, products, prices and orders are invented for teaching.
The five tables at a glance
| Table | One row is | Rows |
|---|---|---|
customers | a person who buys from the shop | 12 |
products | something the shop sells | 16 |
orders | one order placed by a customer | 20 |
order_items | one line of an order: a product and a quantity | 38 |
employees | a member of staff | 8 |
How the tables are linked
The tables point to one another through id numbers. These links are what you write in the ON part of a join.
orders.customer_idholds theidof a row incustomers. Each order belongs to one customer. A customer can have many orders, or none.order_items.order_idholds theidof a row inorders. Each order has one or more lines.order_items.product_idholds theidof a row inproducts. A product can appear in many orders, or in none.employees.manager_idholds theidof another row inemployees: the person's manager. It is empty for the head of the shop.
So the path from a customer to the products they bought runs through four tables: customers, then orders, then order_items, then products. The lesson on joining many tables follows that path.
Things planted in the data on purpose
Real data is untidy, and the lessons need examples of that. So the practice database has a few deliberate features.
- Three customers have no email address. The column holds
NULLfor them, which the lesson on NULL uses. - Three customers have never placed an order, and one product has never been ordered. They are what a LEFT JOIN is for.
- Two products are out of stock, with a stock of 0.
- Two employees earn exactly the same salary, which matters for ranking and for "top N" questions.
- Orders have four statuses:
delivered,shipped,pendingandcancelled. - Three cities have two customers each, and several customers share a state.
Notes on the columns
- Prices and salaries are whole rupees. Salaries are per month.
- Dates are stored as text in year-month-day form, such as
2026-03-15. In this form they sort and compare correctly. The lesson on dates explains how to work with them. - The price of an order line is not stored. It is the quantity in
order_itemstimes the price inproducts. An order's total is the sum over its lines. - Every table except
order_itemshas anidcolumn that is its primary key.
How to see this from SQL
You do not need this page to find out what a database contains. In SQLite, which the practice box runs, this lists the tables:
SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name;Result
| name |
|---|
| customers |
| employees |
| order_items |
| orders |
| products |
5 rows
And this describes the columns of one table:
PRAGMA table_info(customers);Result
| cid | name | type | notnull | dflt_value | pk |
|---|---|---|---|---|---|
| 0 | id | INTEGER | 0 | NULL | 1 |
| 1 | name | TEXT | 1 | NULL | 0 |
| 2 | city | TEXT | 1 | NULL | 0 |
| 3 | state | TEXT | 1 | NULL | 0 |
| 4 | joined | TEXT | 1 | NULL | 0 |
| 5 | TEXT | 0 | NULL | 0 |
6 rows
In MySQL the same jobs are done by SHOW TABLES and DESCRIBE customers. In PostgreSQL and SQL Server, the standard information_schema views hold the lists.
The statements that create and fill the database are in one plain file, which the practice box loads: seed.sql. You can read it to see CREATE TABLE and INSERT used for real, or run it in SQLite on your own computer to get the same database there.
The tables in full
customers (12 rows)
The people who buy from the shop. One row per customer.
Columns: id integer, name text, city text, state text, joined text, email text
| id | name | city | state | joined | |
|---|---|---|---|---|---|
| 1 | Asha Verma | Ludhiana | Punjab | 2025-01-15 | asha@example.com |
| 2 | Ravi Kumar | Delhi | Delhi | 2025-02-03 | ravi@example.com |
| 3 | Meena Gill | Amritsar | Punjab | 2025-03-21 | NULL |
| 4 | Kabir Khan | Mumbai | Maharashtra | 2025-04-10 | kabir@example.com |
| 5 | Sunita Rao | Chennai | Tamil Nadu | 2025-05-05 | sunita@example.com |
| 6 | Arjun Mehta | Pune | Maharashtra | 2025-06-18 | NULL |
| 7 | Priya Nair | Kochi | Kerala | 2025-07-02 | priya@example.com |
| 8 | Imran Ali | Delhi | Delhi | 2025-08-14 | imran@example.com |
| 9 | Neha Joshi | Jaipur | Rajasthan | 2025-09-09 | neha@example.com |
| 10 | Tara Singh | Ludhiana | Punjab | 2025-10-27 | NULL |
| 11 | Vikram Das | Kolkata | West Bengal | 2025-11-30 | vikram@example.com |
| 12 | Joy Thomas | Mumbai | Maharashtra | 2026-01-08 | joy@example.com |
12 rows
Open customers in the practice box
products (16 rows)
What the shop sells. One row per product, with its price in rupees and the number in stock.
Columns: id integer, name text, category text, price integer, stock integer
| id | name | category | price | stock |
|---|---|---|---|---|
| 1 | Basmati Rice 5 kg | Grocery | 650 | 40 |
| 2 | Toor Dal 1 kg | Grocery | 160 | 75 |
| 3 | Sunflower Oil 1 L | Grocery | 145 | 60 |
| 4 | Tea 500 g | Grocery | 280 | 0 |
| 5 | Notebook 200 pages | Stationery | 60 | 300 |
| 6 | Ball Pen pack of 10 | Stationery | 90 | 150 |
| 7 | Geometry Box | Stationery | 120 | 45 |
| 8 | School Bag | Stationery | 750 | 20 |
| 9 | LED Bulb 9 W | Electronics | 110 | 200 |
| 10 | Extension Board | Electronics | 399 | 35 |
| 11 | Earphones | Electronics | 499 | 0 |
| 12 | Power Bank | Electronics | 1299 | 18 |
16 rows
Showing the first 12 of 16 rows.
Open products in the practice box
orders (20 rows)
One row for each order placed. customer_id says who placed it.
Columns: id integer, customer_id integer, order_date text, status text
| id | customer_id | order_date | status |
|---|---|---|---|
| 1 | 1 | 2026-01-05 | delivered |
| 2 | 2 | 2026-01-12 | delivered |
| 3 | 4 | 2026-01-20 | cancelled |
| 4 | 1 | 2026-02-02 | delivered |
| 5 | 5 | 2026-02-14 | delivered |
| 6 | 7 | 2026-02-28 | delivered |
| 7 | 2 | 2026-03-03 | delivered |
| 8 | 8 | 2026-03-15 | delivered |
| 9 | 9 | 2026-03-22 | cancelled |
| 10 | 4 | 2026-04-01 | delivered |
| 11 | 11 | 2026-04-18 | delivered |
| 12 | 1 | 2026-05-06 | delivered |
20 rows
Showing the first 12 of 20 rows.
Open orders in the practice box
order_items (39 rows)
The lines of each order: which product and how many. An order has one or more lines.
Columns: order_id integer, product_id integer, quantity integer
| order_id | product_id | quantity |
|---|---|---|
| 1 | 1 | 2 |
| 1 | 2 | 1 |
| 1 | 5 | 4 |
| 2 | 9 | 4 |
| 2 | 10 | 1 |
| 3 | 12 | 1 |
| 4 | 3 | 2 |
| 4 | 4 | 1 |
| 5 | 13 | 2 |
| 5 | 6 | 1 |
| 6 | 14 | 1 |
| 7 | 5 | 10 |
39 rows
Showing the first 12 of 39 rows.
Open order_items in the practice box
employees (8 rows)
The staff of the shop. manager_id points to another row of the same table.
Columns: id integer, name text, department text, salary integer, manager_id integer, hired text
| id | name | department | salary | manager_id | hired |
|---|---|---|---|---|---|
| 1 | Anita Kapoor | Management | 95000 | NULL | 2019-04-01 |
| 2 | Rohit Bansal | Sales | 60000 | 1 | 2020-06-15 |
| 3 | Deepa Iyer | Sales | 48000 | 2 | 2021-09-01 |
| 4 | Manoj Yadav | Sales | 48000 | 2 | 2022-01-10 |
| 5 | Farah Sheikh | Warehouse | 42000 | 1 | 2020-11-20 |
| 6 | Gopal Reddy | Warehouse | 30000 | 5 | 2023-03-05 |
| 7 | Harpreet Kaur | Support | 36000 | 1 | 2021-02-14 |
| 8 | Nikhil Jain | Support | 33000 | 7 | 2024-07-22 |
8 rows
Open employees in the practice box
Examples on this page were run with SQLite 3.50.4 on 12 November 2026. The results shown are the real results.
This is an independent learning site. It is not connected with the makers of any database product. MySQL, PostgreSQL, SQL Server, Oracle and SQLite are named only so that you know where a piece of SQL works. The shop, its customers and its staff in the practice database are made up.