SKILL PATH · SQL

Query Workbench

Write real SQL against a live dataset in this page. Nothing to install, and every answer is checked for you.

THE DATASET

Two Tables, Eighteen Rows

A small sales dataset, small enough to read and check by eye. Open a table to see what is in it.

orders 12 rows
order_idcustomer_idproductregionvalueorder_date
10011Pro planNorth2402026-03-02
10022StarterSouth602026-03-03
10033Pro planNorth2402026-03-03
10041Add-onNorth452026-03-09
10054Pro planEast2402026-03-11
10062Add-onSouth452026-03-14
10075StarterWest602026-03-18
10083Pro planNorth2402026-03-21
10094StarterEast602026-03-22
10106Pro planSouth2402026-03-29
10111StarterNorth602026-04-02
10125Add-onWest452026-04-05
customers 6 rows
customer_idnamecountrysigned_up
1NordwindSweden2025-11-04
2BluefinUnited Kingdom2025-12-18
3CorelisUnited Kingdom2026-01-09
4HarborlineDenmark2026-01-27
5Vantage FoodsSweden2026-02-14
6Kestrel RetailNorway2026-02-28

This runs a teaching subset of SQL in your browser: SELECT, WHERE, JOIN, GROUP BY, HAVING, ORDER BY, LIMIT and the usual aggregates. Nothing is sent anywhere, and your work is saved on this device.

SIX EXERCISES

Write, Run, Check

Each exercise teaches the syntax first, then gives you a task to write yourself. Unlimited attempts, a hint whenever you want one, and the worked solution after three tries.

0 of 6 exercises solved

1

Exercise 1 of 6

Look at the data

Not attempted

Why this matters: Looking at the raw table is how you find out what one row represents, which decides everything after it.

First, the syntax: SELECT and FROM

Every query answers the same two questions: which columns do you want, and which table are they in? SELECT lists the columns, FROM names the table, and LIMIT stops after a set number of rows so you are not flooded.

The pattern

SELECT column_a, column_b
FROM table_name
LIMIT 10;

A worked example

SELECT name, country
FROM customers
LIMIT 3;

Returns the name and country of the first three customers. A star in place of the column list returns every column.

Your task

Return every column for the first five orders, so you can see what the table holds.

2

Exercise 2 of 6

Filter to what matters

Not attempted

Why this matters: Filtering is how a question becomes a report. Everything else is built on WHERE.

First, the syntax: WHERE

WHERE keeps only the rows that match a condition, and runs before anything is calculated. Text goes in single quotes, numbers do not, and conditions combine with AND and OR.

The pattern

SELECT column_a
FROM table_name
WHERE column_b = 'some text'
  AND column_c > 100;

A worked example

SELECT name
FROM customers
WHERE country = 'Sweden';

Returns Nordwind and Vantage Foods. Swap = for <>, <, >, <= or >=, and use LIKE '%plan' for partial matches.

Your task

The North region manager wants only their orders. Return the order id, product and value for orders in the North region.

3

Exercise 3 of 6

Count and group

Not attempted

Why this matters: Counting by a dimension answers most questions people bring to a dataset.

First, the syntax: GROUP BY and COUNT

GROUP BY collapses many rows into one row per value, and COUNT(*) says how many rows fell into each group. AS renames the result so it reads well, and ORDER BY sorts it, with DESC for highest first.

The pattern

SELECT column_a, COUNT(*) AS how_many
FROM table_name
GROUP BY column_a
ORDER BY how_many DESC;

A worked example

SELECT country, COUNT(*) AS customers
FROM customers
GROUP BY country
ORDER BY customers DESC;

Turns six customer rows into one row per country, with a count against each.

Your task

How many orders did each region take? Return the region and the number of orders, with the busiest region first.

4

Exercise 4 of 6

Add up the money

Not attempted

Why this matters: Volume and value tell different stories. The most ordered product is often not the most valuable.

First, the syntax: SUM, AVG, MIN and MAX

COUNT tells you how many. SUM adds a column up, AVG averages it, and MIN and MAX find the extremes. Each needs to know what it is grouped by, unless you want one total for the whole table.

The pattern

SELECT column_a, SUM(number_column) AS total
FROM table_name
GROUP BY column_a
ORDER BY total DESC;

A worked example

SELECT region, AVG(value) AS average_order
FROM orders
GROUP BY region;

Gives the average order value in each region. Replace AVG with SUM for the total, or MAX for the largest single order.

Your task

Which product brings in the most revenue? Return each product and its total value, highest first.

5

Exercise 5 of 6

Join two tables

Not attempted

Why this matters: Real answers almost always need two tables joined on a shared key.

First, the syntax: JOIN

Most useful answers need two tables. A JOIN matches rows in one table to rows in another using a column they share, usually an id. A short alias such as o or c keeps it readable, and you then write alias.column.

The pattern

SELECT a.column_1, b.column_2
FROM table_a a
JOIN table_b b ON a.shared_id = b.shared_id;

A worked example

SELECT o.order_id, c.name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
LIMIT 5;

Puts the customer name beside each order. The id is how the tables connect; the name is what the business reads.

Your task

Finance wants spend by customer name, not by id. Return each customer name and their total spend, highest first.

6

Exercise 6 of 6

Answer a real question

Not attempted

Why this matters: HAVING filters after grouping, which is the part that trips up most people the first time.

First, the syntax: HAVING

WHERE filters rows before grouping. HAVING filters the groups afterwards, which is what you need when the condition depends on an aggregate. Using one where you meant the other is the most common SQL mistake.

The pattern

SELECT column_a, SUM(number_column) AS total
FROM table_name
GROUP BY column_a
HAVING SUM(number_column) > 1000;

A worked example

SELECT product, COUNT(*) AS orders
FROM orders
GROUP BY product
HAVING COUNT(*) > 3;

Keeps only the products ordered more than three times. The same condition in WHERE would fail, because the count does not exist yet.

Your task

A manager asks: which countries spend more than £300 with us? Return the country and total spend, for countries above £300 only.

Build Your Confidence with Data

This workbench is the practice block behind every SQL lesson on Insyt.