SQL · Guides · October 30, 2026 · 9 min read
SQL for beginners: how to learn SQL step by step (with a 4-week plan)

SQL (Structured Query Language) is the language for asking questions of data stored in tables: “how many flights were cancelled last week”, “which routes bring in the most revenue”. You do not need to know programming to start, and you do not need to install anything if you use an online SQL environment. The fastest way to learn is in this order: read a table with SELECT, filter it with WHERE, sort it with ORDER BY, summarise it with COUNT and GROUP BY, and combine tables with JOIN, writing real queries at every step. With around an hour a day, most beginners can write useful queries on their own within two to four weeks.
This page is the “how to learn” overview: one short example per step, a week-by-week plan and what to avoid. For each step in depth, follow the links to the dedicated guides. All examples run on the airline database from the Nomto SQL course, in PostgreSQL syntax on DuckDB (the engine of the Nomto SQL room), and every result table is the real output.
What SQL is and why it is worth learning first
Data in companies usually lives in databases, and a database is a set of tables. Each table is like a spreadsheet with strict rules: every row is one thing (a flight, a booking, a ticket), every column has one type (text, number, date). SQL is how you get answers out of those tables without exporting them anywhere.
A few things make SQL beginner-friendly:
- It is declarative. You describe the result you want (“flights from Kazan that were cancelled”), and the database works out how to get it. There are no loops or variables at the beginner level.
- The core is small. Six or seven clauses cover most of what analysts write every day.
- It barely changes. A
SELECTwritten thirty years ago still runs today, and the basics are the same in PostgreSQL, MySQL, SQL Server, SQLite, BigQuery and DuckDB. Dialects differ in details such asLIMITversusTOP, but you can switch between them in a day.
SQL is used by data and product analysts, marketers, finance teams, developers and testers. If you are aiming for an analyst role, the data analyst roadmap shows where SQL fits among the other skills.
What you need to start
- A database with real-looking data. Toy tables with five rows teach syntax but hide the problems you meet in real work, such as duplicates after a join or empty values. The course database used here has 104 airports, 33,121 flights and 262,788 bookings.
- A place to run queries. The Nomto SQL room runs in the browser. If you prefer a local setup, DuckDB or SQLite need no server; PostgreSQL is the most common choice for learning a “full” database.
- Questions to answer. Learning goes faster when each query answers something: “which city has the most departures?” sticks better than “practise GROUP BY”.
Step 1: your first SELECT
Every query starts with SELECT (which columns) and FROM (which table). * means all columns; LIMIT keeps the result short while you look around:
SELECT *
FROM aircrafts
LIMIT 3;
| aircraft_code | model | range |
|---|---|---|
| 319 | Airbus A319-100 | 6700 |
| 320 | Airbus A320-200 | 5700 |
| 321 | Airbus A321-200 | 5600 |
That is a complete, valid SQL query. Before writing anything clever, run SELECT * ... LIMIT 5 on every table you are going to use and answer one question: what does one row mean? In flights it is one departure, in tickets one passenger’s ticket, in ticket_flights one passenger on one flight. Almost every wrong number beginners produce comes from not knowing this.
Step 2: filter rows with WHERE
WHERE keeps only the rows that meet a condition. Combine conditions with AND and OR; text goes in single quotes:
SELECT flight_no, arrival_airport, scheduled_departure
FROM flights
WHERE departure_airport = 'KZN'
AND status = 'Cancelled'
ORDER BY scheduled_departure;
| flight_no | arrival_airport | scheduled_departure |
|---|---|---|
| PG0446 | MRV | 2026-09-08 11:25:00 |
| PG0579 | PKV | 2026-09-09 15:45:00 |
| PG0508 | LED | 2026-09-10 09:45:00 |
| PG0498 | IKT | 2026-09-10 10:15:00 |
| PG0610 | ROV | 2026-09-10 12:45:00 |
| PG0621 | MQF | 2026-09-10 16:05:00 |
| PG0039 | KVX | 2026-09-10 17:25:00 |
| PG0203 | DME | 2026-09-10 17:45:00 |
| PG0525 | MCX | 2026-09-10 18:45:00 |
Nine cancelled departures from Kazan. Text comparison is exact: status = 'cancelled' with a lower-case c returns 0 rows here, against 414 cancelled flights overall. Next, learn IN, BETWEEN, pattern matching with LIKE and IS NULL for empty values (= NULL never works; the NULL guide explains why).
Step 3: sort with ORDER BY
ORDER BY sorts the result, DESC reverses it, and together with LIMIT it answers “top N” questions. The query above already uses it to list flights in time order. One rule to learn early: without ORDER BY the order of rows is not guaranteed, so a LIMIT without it gives you “some rows”, not “the first rows”. The ORDER BY guide covers sorting by several columns, where empty values go and ties.
Step 4: summarise with aggregates and GROUP BY
Aggregate functions turn many rows into one number:
SELECT COUNT(*) AS bookings,
ROUND(AVG(total_amount), 2) AS avg_booking
FROM bookings;
| bookings | avg_booking |
|---|---|
| 262788 | 790.26 |
Add GROUP BY and you get one row per group instead, which is how most reports are built. Bookings and revenue by month:
SELECT date_trunc('month', book_date) AS month,
COUNT(*) AS bookings,
ROUND(SUM(total_amount)) AS revenue
FROM bookings
GROUP BY month
ORDER BY month;
| month | bookings | revenue |
|---|---|---|
| 2026-06-01 00:00:00 | 24952 | 19647411 |
| 2026-07-01 00:00:00 | 171646 | 135972835 |
| 2026-08-01 00:00:00 | 66190 | 52049563 |
Before you conclude that sales peaked in July, check the date range: MIN(book_date) is 17 June and MAX(book_date) is 11 August, so June and August are partial months. Checking the edges of the data is a habit worth building from day one. The details of COUNT(*) versus COUNT(column), HAVING and conditional counts are in SQL aggregate functions and GROUP BY vs HAVING.
Step 5: combine tables with JOIN
Real questions need more than one table. flights stores airport codes, airports stores the city names; a JOIN matches them on the code:
SELECT a.city, COUNT(*) AS departures
FROM flights f
JOIN airports a ON a.airport_code = f.departure_airport
GROUP BY a.city
ORDER BY departures DESC
LIMIT 5;
| city | departures |
|---|---|
| Moscow | 7917 |
| St. Petersburg | 1900 |
| Novosibirsk | 1055 |
| Krasnoyarsk | 707 |
| Yekaterinburg | 689 |
Moscow has three airports, so grouping by city adds them together. Joins are where beginners hit their first truly confusing results: rows disappear (an INNER JOIN drops unmatched rows) or multiply (one row matches several). Spend extra time here with SQL joins explained.
After these five steps you know the core. Basic SQL queries walks through each clause in more depth with more examples, and the SQL cheat sheet is a one-page reminder of the syntax.
A 2–4 week plan to learn SQL
The plan below assumes about an hour a day, five days a week. It follows the modules of the Nomto SQL course, but works with any material. If you have more time, compress it into two weeks; if less, stretch it, but keep writing queries every day rather than in one long weekend session.
| Week | Topics | You can answer |
|---|---|---|
| 1 | Tables, rows and keys; SELECT, aliases, DISTINCT; ORDER BY, LIMIT; WHERE with AND, OR, IN, BETWEEN, LIKE, IS NULL |
“Which flights from Kazan were cancelled?” |
| 2 | Arithmetic and rounding; text and date functions; COUNT, SUM, AVG, MIN, MAX; GROUP BY, HAVING |
“How many bookings and how much revenue per month?” |
| 3 | INNER JOIN, LEFT JOIN, joining several tables, row multiplication; CASE WHEN; NULL handling |
“Departures per city, split into short and long flights” |
| 4 | Subqueries, WITH (CTEs), UNION, EXCEPT; two or three end-to-end tasks |
“Which routes bring in the most revenue, and which aircraft is never used?” |
How to spend each hour:
- 10 minutes of reading about one topic, no more.
- 40 minutes of writing queries. Type them yourself; copying and pasting teaches much less. Change the examples: another city, another column, another sort order.
- 10 minutes of checking. Does the number make sense? If you counted flights per city, do the cities add up to the total?
At the end of week 4, do the SQL practice problems without looking at the answers. If you can solve most of the first ten, you have the basics. Window functions, date spines and cohort analysis are the next level, not part of the first month.
Common beginner mistakes
- Learning syntax without data. Reading about
JOINis not the same as seeing a join double your totals. Run every example. - Not knowing what one row means. Counting
ticketswhen you meant bookings gives a number 40% too high on this data (366,733 tickets, 262,788 bookings). - Double quotes for text. In PostgreSQL and DuckDB,
"Moscow"is a column name; text values need single quotes,'Moscow'. = NULLinstead ofIS NULL. It returns nothing, without an error.LIMITwithoutORDER BY. The result looks like a top 10 but is arbitrary.- Trusting a query because it ran. No error does not mean the right answer. Check totals, edges (first and last dates) and a few rows by hand.
- Jumping to advanced topics too early. Window functions make sense once
GROUP BYandJOINfeel automatic, not before. - Only watching videos. Passive learning feels productive and leaves you stuck at the first blank editor.
How to know you are ready for the next step
You have the basics when you can, without looking anything up:
- explore an unfamiliar table and say what one row represents;
- filter, sort and limit a result;
- count and sum per group, and filter groups with
HAVING; - join two or three tables and explain why the row count changed;
- spot a wrong number by checking it against a total.
From there, the usual next steps are subqueries, CTEs, window functions and date handling. If you are preparing for a job, the SQL interview questions show what is typically asked.
FAQ
Can I learn SQL with no programming experience?
Yes. SQL is often the first technical skill people learn, because a query reads almost like an English sentence and there is no need for loops, variables or setting up a project. Comfort with spreadsheets helps, but it is not required.
How long does it take to learn SQL for beginners?
The basics (SELECT, WHERE, ORDER BY, aggregates, GROUP BY, JOIN) usually take two to four weeks at around an hour a day. Becoming fluent with subqueries, CTEs and window functions takes longer and comes mostly from practice on real questions.
Which SQL dialect should a beginner learn?
PostgreSQL syntax is a good default: it is close to the SQL standard, widely used, and free. Everything you learn transfers to MySQL, SQL Server, BigQuery or Snowflake with minor changes, for example TOP instead of LIMIT in SQL Server.
Do I need to install a database to learn SQL?
No. You can start in a browser-based SQL environment such as the Nomto SQL room. Installing PostgreSQL, DuckDB or SQLite locally is useful later, but it is not a prerequisite for learning the language.
Is SQL hard to learn?
The syntax is not. The hard part is thinking in sets of rows: knowing what each table represents, what a join does to row counts, and how NULL behaves. That comes from writing queries on realistic data and checking the results, which is why practice matters more than reading.
What should I learn after SQL basics?
Subqueries and CTEs, then window functions and date functions. If your goal is an analyst job, add spreadsheets, basic statistics and a BI tool, as described in the data analyst roadmap.