SQL Tutorial › Getting Started › The Sample Database

The SQL Sample Database

BeginnerLesson 6 of 698 min read1 queries run on MySQL 8.4

Every lesson in this tutorial queries the same small company database, so you can focus on SQL instead of new data each time. It has six related tables: a company’s departments and employees, and its online shop’s customers, products, orders and order items. This page shows every row and gives you the script to create it on your own MySQL server.

Advertisement
In this lesson
  • What each table holds and how the tables are linked
  • Which rows make interesting edge cases (NULLs, unmatched rows, ties)
  • How to create the database on your own server

How the tables are linked

TablePrimary keyLinks toRows
departmentsdept_id5
employeesemp_iddept_id → departments, manager_id → employees12
customerscustomer_id7
productsproduct_id9
ordersorder_idcustomer_id → customers10
order_itemsorder_id + product_idorder_id → orders, product_id → products16
  • HR side: each employee belongs to a department and reports to a manager, who is also an employee (manager_id points back to employees). The chain goes four levels deep: CEO → manager → senior developer → developer.
  • Shop side: a customer places orders; each order has one or more order items; each item is a product with a quantity. Line amount = quantity × price.

departments

departments · 5 rows
dept_iddept_namelocation
1EngineeringBengaluru
2SalesMumbai
3MarketingPune
4HRDelhi
5FinanceMumbai

Finance (dept 5) has no employees: useful for LEFT JOIN examples.

employees

employees · 12 rows
emp_idfirst_namelast_namedept_idmanager_idjob_titlesalarycommissionhire_datecity
100MeeraKapoorNULLNULLCEO250000NULL2015-01-05Mumbai
101AshaRao1100Engineering Manager125000NULL2018-04-12Bengaluru
102RahulMehta1101Senior Developer98000NULL2019-07-01Bengaluru
103PriyaNair1101QA Engineer72000NULL2021-01-18Pune
104KaranShah1102Developer72000NULL2022-08-29Bengaluru
105VikramSingh2100Sales Manager105000120002017-11-20Mumbai
106NehaGupta2105Sales Executive5400060002022-03-14Mumbai
107ArjunDas2105Sales Executive4800045002023-06-05Kolkata
108KavyaIyer3100Marketing Lead88000NULL2020-09-09Pune
109RohanJoshi3108Content Writer45000NULL2024-01-22Pune
110SnehaKulkarni4100HR Manager78000NULL2019-02-25Delhi
111AmitVerma1101Intern25000NULL2025-06-02Bengaluru

Rows worth noticing:

  • Meera Kapoor (100), the CEO, has no department and no manager (NULL).
  • Priya Nair and Karan Shah both earn 72,000: a tie, which matters for RANK and DENSE_RANK.
  • Only the three Sales staff have a commission; it is NULL for everyone else (NULL Values).

customers

customers · 7 rows
customer_idcustomer_nameemailcityjoined_on
1Ananya Sharmaananya@example.comMumbai2024-01-15
2Rohit Kumarrohit.k@example.comDelhi2024-02-03
3Fatima Khanfatima@example.comHyderabad2024-03-21
4David FernandesNULLGoa2024-05-09
5Ishita Boseishita@example.comKolkata2024-07-30
6Manoj Pillaimanoj.p@example.comChennai2025-01-11
7Sara Thomassara.t@example.comBengaluru2025-03-02

David Fernandes has no email, and Manoj Pillai and Sara Thomas have never ordered.

products

products · 9 rows
product_idproduct_namecategorypricestock
1Wireless MouseElectronics799120
2Mechanical KeyboardElectronics349945
3USB-C HubElectronics19990
4Office ChairFurniture899912
5Standing DeskFurniture189995
6Notebook PackStationery249300
7Gel PensStationery199250
8Desk LampFurniture149930
9Monitor ArmFurniture279918

The USB-C Hub is out of stock (stock = 0), and the Monitor Arm has never been ordered.

orders

orders · 10 rows
order_idcustomer_idorder_datestatus
100112025-01-05Delivered
100222025-01-17Delivered
100312025-02-02Delivered
100432025-02-14Cancelled
100542025-03-08Delivered
100652025-03-22Shipped
100722025-04-10Delivered
100812025-04-28Pending
100932025-05-15Delivered
101052025-06-01Delivered

order_items

order_items · 16 rows
order_idproduct_idquantity
100121
100165
100241
100311
100321
100451
1005610
100574
100632
100681
100711
100842
100882
100921
101063
101072

A first look across the tables

How much did each order cost? This joins three tables. You will learn every part of it in the coming lessons:

SQL
SELECT o.order_id,       c.customer_name,       o.status,       SUM(oi.quantity * p.price) AS order_totalFROM orders oJOIN customers   c  ON c.customer_id = o.customer_idJOIN order_items oi ON oi.order_id   = o.order_idJOIN products    p  ON p.product_id  = oi.product_idGROUP BY o.order_id, c.customer_name, o.statusORDER BY o.order_id;
ResultMySQL 8.4
order_idcustomer_namestatusorder_total
1001Ananya SharmaDelivered4744
1002Rohit KumarDelivered8999
1003Ananya SharmaDelivered4298
1004Fatima KhanCancelled18999
1005David FernandesDelivered3286
1006Ishita BoseShipped5497
1007Rohit KumarDelivered799
1008Ananya SharmaPending20996
1009Fatima KhanDelivered3499
1010Ishita BoseDelivered1145
10 rows in set
How this query works, step by step
  1. FROM orders o starts from the 10 orders (o is a short alias).
  2. The three JOINs attach the customer, the order’s items and each item’s product.
  3. quantity * price is the amount of one line; SUM(...) adds the lines of each order.
  4. GROUP BY makes one result row per order, and ORDER BY sorts by order number.

Create it on your own server

Create the database, select it, then run the script below (copy it into the mysql client, MySQL Workbench or any SQL tool):

MySQL
CREATE DATABASE company;USE company;
company.sql
-- sqatools.in SQL tutorial: the "company" sample database (runs unchanged on MySQL 8.4 and SQLite)CREATE TABLE departments (  dept_id   INT PRIMARY KEY,  dept_name VARCHAR(50) NOT NULL,  location  VARCHAR(50));INSERT INTO departments VALUES(1, 'Engineering', 'Bengaluru'),(2, 'Sales', 'Mumbai'),(3, 'Marketing', 'Pune'),(4, 'HR', 'Delhi'),(5, 'Finance', 'Mumbai'); CREATE TABLE employees (  emp_id     INT PRIMARY KEY,  first_name VARCHAR(30) NOT NULL,  last_name  VARCHAR(30) NOT NULL,  dept_id    INT,  manager_id INT,  job_title  VARCHAR(40),  salary     INT,  commission INT,  hire_date  DATE,  city       VARCHAR(30),  FOREIGN KEY (dept_id) REFERENCES departments (dept_id));INSERT INTO employees VALUES(100, 'Meera', 'Kapoor', NULL, NULL, 'CEO', 250000, NULL, '2015-01-05', 'Mumbai'),(101, 'Asha', 'Rao', 1, 100, 'Engineering Manager', 125000, NULL, '2018-04-12', 'Bengaluru'),(102, 'Rahul', 'Mehta', 1, 101, 'Senior Developer', 98000, NULL, '2019-07-01', 'Bengaluru'),(103, 'Priya', 'Nair', 1, 101, 'QA Engineer', 72000, NULL, '2021-01-18', 'Pune'),(104, 'Karan', 'Shah', 1, 102, 'Developer', 72000, NULL, '2022-08-29', 'Bengaluru'),(105, 'Vikram', 'Singh', 2, 100, 'Sales Manager', 105000, 12000, '2017-11-20', 'Mumbai'),(106, 'Neha', 'Gupta', 2, 105, 'Sales Executive', 54000, 6000, '2022-03-14', 'Mumbai'),(107, 'Arjun', 'Das', 2, 105, 'Sales Executive', 48000, 4500, '2023-06-05', 'Kolkata'),(108, 'Kavya', 'Iyer', 3, 100, 'Marketing Lead', 88000, NULL, '2020-09-09', 'Pune'),(109, 'Rohan', 'Joshi', 3, 108, 'Content Writer', 45000, NULL, '2024-01-22', 'Pune'),(110, 'Sneha', 'Kulkarni', 4, 100, 'HR Manager', 78000, NULL, '2019-02-25', 'Delhi'),(111, 'Amit', 'Verma', 1, 101, 'Intern', 25000, NULL, '2025-06-02', 'Bengaluru'); CREATE TABLE customers (  customer_id   INT PRIMARY KEY,  customer_name VARCHAR(50) NOT NULL,  email         VARCHAR(60),  city          VARCHAR(30),  joined_on     DATE);INSERT INTO customers VALUES(1, 'Ananya Sharma', 'ananya@example.com', 'Mumbai', '2024-01-15'),(2, 'Rohit Kumar', 'rohit.k@example.com', 'Delhi', '2024-02-03'),(3, 'Fatima Khan', 'fatima@example.com', 'Hyderabad', '2024-03-21'),(4, 'David Fernandes', NULL, 'Goa', '2024-05-09'),(5, 'Ishita Bose', 'ishita@example.com', 'Kolkata', '2024-07-30'),(6, 'Manoj Pillai', 'manoj.p@example.com', 'Chennai', '2025-01-11'),(7, 'Sara Thomas', 'sara.t@example.com', 'Bengaluru', '2025-03-02'); CREATE TABLE products (  product_id   INT PRIMARY KEY,  product_name VARCHAR(50) NOT NULL,  category     VARCHAR(30),  price        INT,  stock        INT);INSERT INTO products VALUES(1, 'Wireless Mouse', 'Electronics', 799, 120),(2, 'Mechanical Keyboard', 'Electronics', 3499, 45),(3, 'USB-C Hub', 'Electronics', 1999, 0),(4, 'Office Chair', 'Furniture', 8999, 12),(5, 'Standing Desk', 'Furniture', 18999, 5),(6, 'Notebook Pack', 'Stationery', 249, 300),(7, 'Gel Pens', 'Stationery', 199, 250),(8, 'Desk Lamp', 'Furniture', 1499, 30),(9, 'Monitor Arm', 'Furniture', 2799, 18); CREATE TABLE orders (  order_id    INT PRIMARY KEY,  customer_id INT NOT NULL,  order_date  DATE NOT NULL,  status      VARCHAR(20) NOT NULL,  FOREIGN KEY (customer_id) REFERENCES customers (customer_id));INSERT INTO orders VALUES(1001, 1, '2025-01-05', 'Delivered'),(1002, 2, '2025-01-17', 'Delivered'),(1003, 1, '2025-02-02', 'Delivered'),(1004, 3, '2025-02-14', 'Cancelled'),(1005, 4, '2025-03-08', 'Delivered'),(1006, 5, '2025-03-22', 'Shipped'),(1007, 2, '2025-04-10', 'Delivered'),(1008, 1, '2025-04-28', 'Pending'),(1009, 3, '2025-05-15', 'Delivered'),(1010, 5, '2025-06-01', 'Delivered'); CREATE TABLE order_items (  order_id   INT,  product_id INT,  quantity   INT NOT NULL,  PRIMARY KEY (order_id, product_id),  FOREIGN KEY (order_id) REFERENCES orders (order_id),  FOREIGN KEY (product_id) REFERENCES products (product_id));INSERT INTO order_items VALUES(1001, 2, 1), (1001, 6, 5),(1002, 4, 1),(1003, 2, 1), (1003, 1, 1),(1004, 5, 1),(1005, 6, 10), (1005, 7, 4),(1006, 3, 2), (1006, 8, 1),(1007, 1, 1),(1008, 4, 2), (1008, 8, 2),(1009, 2, 1),(1010, 6, 3), (1010, 7, 2);
Tip

The script uses only standard types (INT, VARCHAR, DATE), so it also runs unchanged on SQLite and needs only small changes for PostgreSQL or SQL Server.

Sample database FAQ

Where can I get a sample database to practise SQL?

Copy the script on this page into MySQL to get the six-table company database used in every lesson of this tutorial. It is small enough to check every result by hand.

Why does the sample data contain NULLs and unmatched rows?

Real data is messy. An employee without a department, customers without orders and a product never sold are exactly the cases that make joins, NULL handling and aggregates behave differently, so every lesson can show them.

Can I change the sample data?

Yes. Run INSERT, UPDATE and DELETE freely; to start over, drop the database and run the script again. The Try it editors in the lessons always start from a fresh copy.