Kiks & Learn
Start learning ↗
SQL / Beginner

SQL foundations: ask better questions

Learn SQL by asking a small sales database clear questions with SELECT, JOIN, GROUP BY, and hands-on queries explained in plain language.

YOUR FREE LEARNING PATH

Learn it here, one small step at a time.

4 guided lessons · About 2h 30m including practice · No subscription

  • Read and filter rows with SELECT and WHERE
  • Connect related tables with JOIN
  • Summarize results with GROUP BY and HAVING
SELECT region, SUM(amount)FROM sales GROUP BY region;Ask a precise question of your dataSales rowsGrouped answers
A database query filtering rows and joining related tables
4 lessons · FreeOptional official free reference ↗
LESSON 01 / 30 MINUTES

Ask for rows with SELECT

SQL is a way to ask a database a precise question. A table stores rows (records) and columns (fields). SELECT chooses what to show, FROM chooses the table, and WHERE keeps only rows that match a condition. SQL keywords are often written in capitals for readability; names and text values still need to match the database.

Try each part in order: choose the table, choose a few useful columns, then narrow the result. Finish a statement with a semicolon.

Sample `sales` rows
sale_idregionitemamount
1NorthNotebook12
2SouthPen10
3NorthFolder15
TRY IT YOURSELF

Write a query that shows only `region` and `amount` for rows where amount is at least 12. Then change the condition to `region = 'North'`.

Reveal a suggested answer

It keeps only rows whose region value is North; it does not choose which columns appear.

Optional further reading

Core lesson and practice are on this page. For more detail, visit the official free reference ↗.

LESSON 02 / 30 MINUTES

Match records with JOIN

Related information is often stored in separate tables. A customer table can have one row per customer, while an orders table has one row per order. JOIN matches the tables using a shared key such as customer_id. Use a table alias to make long queries easier to read.

INNER JOIN returns matches from both sides. LEFT JOIN keeps every row on the left and fills missing right-side values with NULL. Check how many rows you get; a join can create extra rows when a key is not unique.

Two related tables
TableKeyOne row represents
customerscustomer_idOne customer
orderscustomer_idOne order
joined resultcustomer_idOne matching customer-order pair
TRY IT YOURSELF

Join `customers` to `orders` on `customer_id`. Use a LEFT JOIN and look for rows where `orders.order_id IS NULL` to find customers without orders.

Reveal a suggested answer

A customer may have several orders, so there is one result row for each matching customer-order pair.

Optional further reading

Core lesson and practice are on this page. For more detail, visit the official free reference ↗.

LESSON 03 / 30 MINUTES

Count and group results

An aggregate turns many rows into a summary: COUNT(*) counts rows and SUM(amount) adds amounts. GROUP BY region asks for one summary per region. Use WHERE to filter individual rows before grouping; use HAVING to filter completed groups afterward.

A summary is only meaningful when the grouping level is clear. Grouping sales by Region answers a different question from grouping by Region and Item.

SQL clause order to remember
ClauseSimple meaningExample
WHEREChoose rows firstWHERE amount > 10
GROUP BYMake groupsGROUP BY region
HAVINGChoose groupsHAVING SUM(amount) > 20
ORDER BYSort the resultORDER BY total DESC
TRY IT YOURSELF

Calculate total sales and number of sales per region. Keep only regions with a total above 20, and sort the largest total first.

Reveal a suggested answer

HAVING filters groups; WHERE filters the original rows before grouping.

Optional further reading

Core lesson and practice are on this page. For more detail, visit the official free reference ↗.

LESSON 04 / 30 MINUTES

Put the query together

Here is a complete question: “Which regions sold more than $20?” Translate it into steps: select the region, add amounts, group by region, keep groups above 20, then sort. Read the query from the data source through the filters instead of memorizing a magic line.

SELECT region, SUM(amount) AS total_sales
FROM sales
GROUP BY region
HAVING SUM(amount) > 20
ORDER BY total_sales DESC;

Test a query on a few known rows and check its total against the source. A clear column alias, such as total_sales, makes the result easier for another person to understand.

Before sharing a query
CheckAsk yourself
GrainWhat does one result row represent?
Join keyDoes it match the intended records?
TotalsCan I reconcile them with the source?
TRY IT YOURSELF

Change the query to include a count of sales. Explain in one sentence whether the count means orders or customers.

Reveal a suggested answer

A clear alias labels the result for people and makes it easy to refer to when sorting or using the query elsewhere.

Optional further reading

Core lesson and practice are on this page. For more detail, visit the official free reference ↗.

KEEP BUILDING

Recommended next steps

These paths build on ideas from this course. You can start any of them whenever you are ready.

CHECK YOUR UNDERSTANDING

Your final knowledge check.

Score 80% or more to pass. Sign in to save your best result.

1. Which clause filters groups?
2. How should you finish this learning path?

Sign in and start tracking this course to submit and save your score. Use each lesson’s self-check to practice without an account.

Learn together

Sign in to leave a comment →