SQL from Zero: A Complete Beginner’s Guide (with Practice)

SQL from Zero: A Complete Beginner’s Guide (with Practice)

📎 This article includes 2 downloadable practice files ↓

⏱ 5 min readUpdated 27 September 2026

SQL (Structured Query Language) is how you ask questions of a database. It has been around since the 1970s and is still the most useful data skill after Excel: almost every business system — SAP HANA, Oracle, SQL Server, PostgreSQL, MySQL — speaks it. This guide takes you from nothing to writing real reporting queries. Every example can be run in the SQL Playground on this site.

In this article
  1. 1. Tables, rows and columns
  2. 2. SELECT: choosing columns
  3. 3. WHERE: filtering rows
  4. 4. ORDER BY and calculated columns
  5. 5. Aggregates and GROUP BY — SQL’s pivot table
  6. 6. JOIN — combining tables
  7. 7. NULL — the value that is not a value
  8. 8. CASE — IF for SQL
  9. 9. Subqueries and CTEs
  10. 10. Window functions: rankings and running totals
  11. 11. Changing data: INSERT, UPDATE, DELETE
  12. 12. Creating tables
  13. 13. The order SQL really runs in
  14. 14. A practice plan

1. Tables, rows and columns

A database table is like a very disciplined Excel sheet: every column has a name and a data type (number, text, date), and every row is one record. Our practice table sales has one row per sale:

id rep region product qty price sale_date
1 Asha North Monitor 4 11499 2025-02-03

Unlike Excel, you never “scroll” a table — you describe the result you want, and the database works out how to get it.

2. SELECT: choosing columns

SELECT rep, product, qty
FROM sales;

SELECT * returns every column — handy for exploring, but name the columns in real queries so they keep working when the table changes. Add LIMIT 10 (MySQL, PostgreSQL, SQLite) or TOP 10 (SQL Server) to peek at a few rows.

3. WHERE: filtering rows

SELECT * FROM sales
WHERE region = 'North'
  AND qty >= 5
  AND sale_date BETWEEN '2025-01-01' AND '2025-03-31';
Operator Example
= , <> , < , >= qty > 10
IN region IN ('North', 'East')
BETWEEN price BETWEEN 500 AND 2000 (inclusive)
LIKE rep LIKE 'A%' (starts with A)
IS NULL phone IS NULL (never = NULL)
💡 Text values use single quotes. Double quotes are for column names in many databases.

4. ORDER BY and calculated columns

SELECT id, rep, qty * price AS amount
FROM sales
ORDER BY amount DESC;

AS gives a calculated column a name. DESC sorts largest first.

5. Aggregates and GROUP BY — SQL’s pivot table

SELECT region,
       COUNT(*)         AS orders,
       SUM(qty * price) AS revenue,
       AVG(qty)         AS avg_qty
FROM sales
GROUP BY region
ORDER BY revenue DESC;

Every column in SELECT must either be in GROUP BY or be inside an aggregate (COUNT, SUM, AVG, MIN, MAX). Filter groups with HAVING: HAVING SUM(qty*price) > 100000.

6. JOIN — combining tables

Real databases split data across tables to avoid repeating it. JOIN puts it back together — it is VLOOKUP for whole tables.

SELECT s.id, s.region, r.manager, s.qty * s.price AS amount
FROM sales s
LEFT JOIN regions r ON s.region = r.region;
Join Keeps
INNER JOIN Only rows that match in both tables
LEFT JOIN All rows from the left table; blanks (NULL) where no match
RIGHT / FULL JOIN All rows from the right / both tables
⚠️ If a JOIN suddenly multiplies your totals, the key is not unique in one table (e.g. two rows for the same region). Check with SELECT region, COUNT(*) FROM regions GROUP BY region HAVING COUNT(*) > 1.

7. NULL — the value that is not a value

NULL means “unknown”. It is not zero and not an empty string, and any comparison with NULL is unknown too — so WHERE discount = NULL returns nothing. Use IS NULL, and replace NULLs with COALESCE(discount, 0).

8. CASE — IF for SQL

SELECT id, qty,
  CASE WHEN qty >= 20 THEN 'Large'
       WHEN qty >= 5  THEN 'Medium'
       ELSE 'Small' END AS order_size
FROM sales;

9. Subqueries and CTEs

-- sales above the average sale
SELECT * FROM sales
WHERE qty * price > (SELECT AVG(qty * price) FROM sales);

-- the same idea, more readable with a CTE
WITH totals AS (
  SELECT rep, SUM(qty * price) AS revenue
  FROM sales GROUP BY rep
)
SELECT * FROM totals WHERE revenue > 50000 ORDER BY revenue DESC;

A CTE (WITH … AS) is a named temporary result — like a helper sheet that exists only for this query.

10. Window functions: rankings and running totals

SELECT rep, region, qty * price AS amount,
       RANK() OVER (PARTITION BY region ORDER BY qty * price DESC) AS rank_in_region,
       SUM(qty * price) OVER (ORDER BY sale_date) AS running_total
FROM sales;

Window functions calculate across related rows without collapsing them the way GROUP BY does — perfect for top-N per group and cumulative totals.

11. Changing data: INSERT, UPDATE, DELETE

INSERT INTO sales (id, rep, region, product, qty, price, sale_date)
VALUES (41, 'Neha', 'West', 'Hub', 3, 2199, '2025-06-30');

UPDATE sales SET price = 649 WHERE product = 'Mouse';

DELETE FROM sales WHERE qty = 0;
⚠️ An UPDATE or DELETE without WHERE changes every row. Run the matching SELECT first, and use transactions (BEGIN … COMMIT / ROLLBACK) on real systems.

12. Creating tables

CREATE TABLE regions (
  region  VARCHAR(20) PRIMARY KEY,
  manager VARCHAR(50) NOT NULL
);

A primary key guarantees each row is unique. An index (CREATE INDEX idx_sales_region ON sales(region);) makes filters and joins on that column fast.

13. The order SQL really runs in

FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT. That is why you cannot use a SELECT alias in WHERE, but you can in ORDER BY.

14. A practice plan

  1. Run every query above in the SQL Playground.
  2. Solve its six challenges without looking at the answers.
  3. Download the CSV files from SQL for Excel users and load them into DB Browser for SQLite.
  4. Recreate one of your own Excel reports in SQL.

Converting your own CSV files into tables? Use the CSV to SQL converter.

📎 Practice files for this article

  • 🧾
    Sales table (CSV)Load into DB Browser for SQLite to run every query in the guide.
    ⬇ CSV · 3 KB
  • 🧾
    Regions table (CSV)For the JOIN examples.
    ⬇ CSV · 70 B

Free to use for learning. Files with macros (.bas) are plain text — import them with Alt+F11 → File → Import File, and always test on a copy.