Skip to content
Reviewed by Siddharth Sharma Nov 02, 2026

Home › Guides › How to learn SQL in 8 weeks

Tech Explained · 2026

How to Learn SQL in 8 Weeks: A 2026 Roadmap With Real Queries and Free Practice

How to learn SQL in 8 weeks works if you practise queries instead of watching them: spend roughly 60 hours in total, start in SQLite with nothing to install, learn SELECT, WHERE, JOIN, GROUP BY and window functions in that order, and finish with two query projects you can defend in an interview.

2 November 202611 min readBy the 360 Digital Transformation Editorial Team
Key takeaways
  • Eight weeks is enough for job-ready analytical SQL at about 8 hours a week. It is not enough for database administration or tuning at scale.
  • Start in SQLite, not PostgreSQL. Python ships the sqlite3 module, so you can load a CSV and run your first join in under ten minutes with no server and no Docker.
  • Five clauses carry most real work: SELECT, WHERE, JOIN, GROUP BY and ORDER BY. Window functions are the sixth, and they are the dividing line between a beginner and a hireable analyst.
  • Dialects differ in small, painful ways. A query that works in PostgreSQL 18 breaks in SQL Server on the LIMIT clause alone, so learn one engine properly and keep a translation table.
  • Two projects beat six tutorials. Interviewers ask about the join you got wrong, not the course you finished.

You have a CSV open in Excel, 140,000 rows, and the pivot table has been spinning for forty seconds. Someone on the call says "just pull it with SQL" and you nod, because saying no is worse. That gap, between knowing SQL exists and being able to answer a question with it by Thursday, is what this plan closes. The scenario running through this guide is a Pune-based support analyst with roughly eight spare hours a week and no database access at work yet. If that is close enough to you, the weeks below will fit.

How to Learn SQL Without Installing Anything (Week 0, 20 Minutes)

Nearly every SQL for beginners guide starts with an install, and nearly every reader loses their first weekend to it. They pick PostgreSQL because a forum thread said so, fight a Docker volume, and never write a SELECT. Skip that. SQLite is a single file, it is already inside Python, and it speaks enough standard SQL to carry you to week six. Download any CSV you care about, then do this:

# one file, no server, no password
sqlite3 shop.db

sqlite> .mode csv
sqlite> .import orders.csv orders
sqlite> .headers on
sqlite> .mode column
sqlite> SELECT COUNT(*) FROM orders;
140238
sqlite> .schema orders
CREATE TABLE orders(order_id TEXT, city TEXT, amount TEXT, order_date TEXT);

Look at that last line, because it is your first real lesson. SQLite imported every column as TEXT, so SUM(amount) will quietly do the wrong thing and order_date > '2026-01-01' will work by accident, through string comparison. Column types are not a week seven detail. They are what makes your first number wrong. Declare the table before you import:

sqlite3 shop.db
sqlite> CREATE TABLE orders (
   ...>   order_id   TEXT PRIMARY KEY,
   ...>   city       TEXT NOT NULL,
   ...>   amount     REAL NOT NULL,
   ...>   order_date TEXT NOT NULL   -- ISO 8601, YYYY-MM-DD
   ...> );
sqlite> .mode csv
sqlite> .import --skip 1 orders.csv orders
sqlite> SELECT ROUND(SUM(amount), 2) FROM orders;
48219904.5

Versions barely matter here. The change log on sqlite.org lists 3.53.1, released on 5 May 2026, as the newest release, and notes that the planned 3.52.0 was withdrawn with its features folded into 3.53.0. Whatever ships with your operating system is fine for learning.

The 8-Week SQL Roadmap 2026, Week by Week

This SQL roadmap assumes eight hours a week, about 60 hours in total. Order matters more than pace: every week depends on the one before it, and the two weeks people skip, 3 and 7, are the two that show up in interviews.

The 8-week SQL plan

Each week ends in something you can run, not something you have watched.

Wk 1

SELECT, WHERE, ORDER BY, LIMIT

Load two CSVs into SQLite and answer ten questions about one table only. Deliverable: a .sql file with ten working queries and the row counts they return.

Wk 2

GROUP BY and aggregation

COUNT, SUM, AVG, MIN, MAX, plus HAVING. Deliverable: revenue by city by month, with a sanity check that the totals match SUM(amount) over the whole table.

Wk 3

JOINs, properly

INNER, LEFT, and the self join. Deliverable: deliberately break a join so it duplicates rows, then write down the row count before and after. This is the week that pays off for years.

Wk 4

Subqueries and CTEs

Rewrite three of your week 3 queries using WITH. Deliverable: one query that is four stacked CTEs and still readable six days later.

Wk 5

Dates, text, NULL and CASE

Date truncation, string splitting, COALESCE, and the three-valued logic that makes WHERE col != 'x' drop your NULL rows. Deliverable: a cohort table by signup month.

Wk 6

Move to PostgreSQL

Same queries, real server, real types. Deliverable: your week 5 cohort query running on Postgres with proper DATE and NUMERIC columns instead of TEXT.

Wk 7

Window functions

ROW_NUMBER, RANK, LAG, LEAD, running totals, and the OVER clause. Deliverable: month-over-month growth and a top-3-per-city ranking, both in one query each.

Wk 8

Project and EXPLAIN

Ship one of the three projects below, add an index, and read the plan before and after. Deliverable: a repo with a README that states the question each query answers.

Pacing assumes roughly 8 hours a week of hands-on querying, checked 2 November 2026.

Those 60 hours should not be spread evenly. Joins and window functions together deserve nearly half your practice time, because that is where correctness and employability both live.

Where 60 hours of SQL practice should go

Joins plus window functions are 45% of the effort and most of the interview.

JOINs and the grain problem25%
Window functions20%
GROUP BY and aggregation18%
SELECT, WHERE, ORDER BY14%
Subqueries and CTEs13%
Types, NULL, indexes, EXPLAIN10%

Split reflects the clauses that appear in analyst job descriptions and interview rounds, as reviewed on 2 November 2026.

If you would rather not self-pace this, the SQL and Excel blocks of 360DT's live Data Analyst course cover weeks 1 through 7 of this plan in guided sessions, with the same queries reviewed line by line. Also read: our SQL commands cheat sheet for the syntax you will keep forgetting in weeks 1 and 2.

How to Learn SQL for Beginners: The Five Clauses That Do Most of the Work

SQL looks like English, and that is a trap, because it does not execute in the order you read it. You write SELECT first, but the engine resolves FROM and JOIN first, then WHERE, GROUP BY, HAVING, SELECT, and only then ORDER BY and LIMIT. That one fact explains most beginner errors, including why a column alias will not work in WHERE. Here is all of weeks 1 and 2 in one query: our Pune analyst wants the ten cities with the highest average order value in the last 90 days, counting only cities with enough orders to mean anything.

SELECT city,
       COUNT(*)                      AS orders,
       ROUND(AVG(amount), 2)         AS avg_order_value
FROM   orders
WHERE  order_date >= DATE('now', '-90 days')
GROUP  BY city
HAVING COUNT(*) >= 50
ORDER  BY avg_order_value DESC
LIMIT  10;

Five clauses, one real question answered. WHERE filters rows before grouping, HAVING filters groups after. Swap them and you get an error or, worse, a plausible wrong answer.

The pipeline your query actually runs through

Knowing what happens after you press enter is what turns guessing into debugging. Your query is text until the parser turns it into a tree, the planner decides how to fetch rows, and the executor does the work against the heap and whatever indexes exist.

From your SQL text to a chart

EXPLAIN shows you the planner's decision, which is the only part you can influence from the query.

How a SQL query is parsed, planned, executed and returned SQL text goes to a parser, then a planner, then an executor. The executor reads the table heap and indexes, returns a result set, and a BI tool or notebook renders it. EXPLAIN reveals the planner output. Your SQL text SELECT city, SUM(...) Parser syntax check Planner scan or index? Executor does the work Table heap & indexes pages on disk or in cache Result set 10 rows Power BI or notebook chart, table, export text tree plan row requests rows out rendered EXPLAIN prints this

Simplified from the parse, plan, execute model documented by PostgreSQL and SQLite; checked 2 November 2026.

JOINs and the Grain Problem Nobody Warns You About

Week 3 is the week to slow down. A join does not add columns, it multiplies rows, and if the right-hand table holds two rows per key your revenue total doubles with no error message at all. Your manager will not catch it. You will, two weeks later, when finance disagrees. Build the habit now: count before, count after.

-- 1. what is the grain of each table?
SELECT COUNT(*), COUNT(DISTINCT order_id) FROM orders;          -- 140238 | 140238
SELECT COUNT(*), COUNT(DISTINCT order_id) FROM order_items;     -- 391044 | 140238

-- 2. so this join CANNOT be used for revenue totals
SELECT SUM(o.amount)
FROM   orders o
JOIN   order_items i ON i.order_id = o.order_id;   -- wrong: 134 crore

-- 3. aggregate first, then join
WITH item_counts AS (
  SELECT order_id, COUNT(*) AS items
  FROM   order_items
  GROUP  BY order_id
)
SELECT ROUND(SUM(o.amount), 2) AS revenue,
       ROUND(AVG(c.items), 2)  AS avg_items_per_order
FROM   orders o
LEFT   JOIN item_counts c ON c.order_id = o.order_id;   -- right: 4.82 crore

That three-step pattern, check the grain, aggregate to the grain you need, then join, is worth more than anything else in this guide. It is also why star schemas exist: a well-built warehouse hands you one fact table at one grain, so you cannot make this mistake by accident.

What usually goes wrong here
  • LEFT JOIN plus a WHERE on the right table. You wrote LEFT JOIN to keep unmatched rows, then filtered WHERE i.status = 'shipped', which silently turns it back into an inner join. Put that condition in the ON clause instead.
  • COUNT(*) after a LEFT JOIN. It counts the join output, not your customers. Use COUNT(DISTINCT o.order_id) when in doubt, and always be able to say which thing you are counting.
  • NULL comparisons. amount != 100 drops every row where amount is NULL, because NULL is not equal to anything, including itself. Write amount IS DISTINCT FROM 100 in PostgreSQL, or wrap in COALESCE.
  • Joining on a float or a formatted string. If the key is '0012' in one table and 12 in the other, you get zero matches and no complaint from the database.

SQL Window Functions: What Separates Week 4 From Week 7

If you learn nothing else after joins, learn SQL window functions. They answer what aggregation cannot: ranking inside a group, comparing a row to the previous row, running totals. People used to solve these with correlated subqueries nobody could read. Here is one business question at two skill levels.

Week 2: what you can write

Monthly revenue. Correct, but it cannot compare months.

SELECT strftime('%Y-%m', order_date) AS mth,
       ROUND(SUM(amount), 2)         AS revenue
FROM   orders
GROUP  BY mth
ORDER  BY mth;

mth      revenue
2026-07  3914220.50
2026-08  4455109.75
2026-09  4201880.00

Run on the sample SQLite database used throughout this guide, 2 November 2026.

Week 7: what gets you hired

Same data, now with month-over-month growth in one pass.

WITH m AS (
  SELECT strftime('%Y-%m', order_date) AS mth,
         SUM(amount)                   AS revenue
  FROM   orders GROUP BY mth
)
SELECT mth,
       ROUND(revenue, 2) AS revenue,
       ROUND(100.0 * (revenue - LAG(revenue) OVER (ORDER BY mth))
             / LAG(revenue) OVER (ORDER BY mth), 1) AS mom_pct
FROM   m ORDER BY mth;

mth      revenue      mom_pct
2026-07  3914220.50   NULL
2026-08  4455109.75   13.8
2026-09  4201880.00   -5.7

LAG returns NULL on the first row, which is correct and worth explaining in an interview.

The other window function to drill is ROW_NUMBER with PARTITION BY, which answers "top 3 products per city" in a way GROUP BY simply cannot:

WITH ranked AS (
  SELECT city, product, SUM(amount) AS rev,
         ROW_NUMBER() OVER (PARTITION BY city ORDER BY SUM(amount) DESC) AS rn
  FROM   orders GROUP BY city, product
)
SELECT city, product, ROUND(rev, 2) AS rev
FROM   ranked WHERE rn <= 3 ORDER BY city, rn;

You cannot filter on rn in the same SELECT that defines it, because window functions are evaluated after WHERE. That is the execution order biting again. Wrap it in a CTE, every time.

Window functions are also where the certification syllabi start: both the Power BI data modelling work in the PL-300 track and the Spark SQL and T-SQL sections of a live Microsoft Fabric data engineering program assume you can write an OVER clause without looking it up.

Where to Practise SQL Free in 2026

None of this costs money. What you do need is a dataset with more than one table, because single-table practice teaches you nothing about joins.

Option What it is Free limit Best for
SQLite on your laptop A single-file database, already inside Python as the sqlite3 module No limit, no account, no server Weeks 1 to 5. Start here.
PostgreSQL locally The real thing. Version 18 is the current stable line, with 18.6 the latest minor released on 13 August 2026 per postgresql.org Free and open source Week 6 onward, real types and real EXPLAIN
BigQuery sandbox Google's warehouse with no billing account attached Google's sandbox documentation states 10 GB of active storage and 1 TB of processed query data per month, with tables expiring after 60 days Practising on large public datasets
Supabase free project Hosted PostgreSQL with a web SQL editor Third-party pricing trackers in 2026 consistently report 500 MB of database per project, and free projects pausing after a week of inactivity Querying from another machine, sharing a database
DuckDB An in-process engine that queries CSV and Parquet files directly Free and open source When your CSV is too big for Excel but too small for a warehouse

One opinion, stated plainly: skip the gamified SQL apps in week 1. They train you to pattern-match a puzzle, and real analysis is never a puzzle with one answer. Load your own messy CSV instead, the one with trailing spaces and two spellings of Bengaluru, because cleaning that is the job. Also read: our DuckDB walkthrough if your files are Parquet rather than a database.

Dialects: where your query breaks when the engine changes

Learn one engine well and keep this table nearby. These five differences cause most of the confusion when you move from a tutorial to your employer's database.

Task PostgreSQL MySQL SQL Server BigQuery
First 10 rows LIMIT 10 LIMIT 10 SELECT TOP 10 LIMIT 10
Join text a || b CONCAT(a,b) a + b CONCAT(a,b)
Month bucket DATE_TRUNC('month', d) DATE_FORMAT(d,'%Y-%m') DATETRUNC(month, d) DATE_TRUNC(d, MONTH)
Null fallback COALESCE(a, 0) IFNULL(a, 0) ISNULL(a, 0) IFNULL(a, 0)
Integer division 7/2 = 3 7/2 = 3.5 7/2 = 3 7/2 = 3.5

That last row has produced more wrong percentages than anything else here. In PostgreSQL and SQL Server, successes / total on two integer columns returns 0, not 0.42. Cast one side: successes * 1.0 / total.

Live course

Learn SQL alongside Excel, Python and Power BI, with your queries reviewed live

Live online·Sat–Sun, 8–11 PM IST·70+ hrs·Rs 24,999

A 10-week live weekend program covering Python, SQL, advanced Excel and Power BI, with preparation for the Microsoft PL-300 certification. Includes hands-on projects, mentor support and placement guidance.

Explore the course
Data Analyst Course: Excel, SQL, Python & Power BI (PL-300)

The Errors You Will Hit, and the Actual Fix

Keep this open in week 2. You will see every one of these verbatim, and the wording is more helpful than it looks once you know what the engine is objecting to.

What you see What it really means Fix
column "city" must appear in the GROUP BY clause You selected a column that is neither grouped nor aggregated Add it to GROUP BY, or wrap it in MIN, MAX or an aggregate you can justify
column "avg_order_value" does not exist in a WHERE clause Aliases are created in SELECT, which runs after WHERE Repeat the expression in WHERE, or wrap the query in a CTE and filter outside
aggregate functions are not allowed in WHERE You meant to filter groups, not rows Move the condition to HAVING
more than one row returned by a subquery used as an expression Your scalar subquery is not scalar Add LIMIT 1 with an ORDER BY you can defend, or convert it to a join
Totals suddenly inflated, no error at all A join changed the grain COUNT(*) before and after the join, then aggregate the many-side first
operator does not exist: text >= date Your date column is stored as text Cast it, or fix the column type. This is why week 6 moves to PostgreSQL

One honest caveat

SQL on its own will not get you an analyst job in 2026, and anyone selling an eight-week plan as a career guarantee is selling you something. Postings that ask for SQL almost always ask for Power BI or Tableau beside it, plus enough Excel to survive the first week and enough Python to clean a file. SQL is the entry ticket, not the whole stack. It is also genuinely bad at some things people try to use it for: complex row-by-row business logic, anything that needs loops, and statistics beyond averages and percentiles. When a query grows to 400 lines of nested CASE statements, the answer is not better SQL. It is to move that logic into a modelling layer such as dbt or into Python.

SQL Practice Projects: Three Builds That Survive an Interview

SQL practice projects are where the eight weeks turn into something you can show. Week 8 exists to produce exactly one artefact. Pick the one you are actually curious about, because curiosity is what carries you through the boring part of cleaning the data.

  1. Retail cohort analysis. Two tables, customers and orders. Produce a monthly cohort retention grid using DATE_TRUNC and a self join on month offset. What the interviewer asks: "how did you handle customers who bought twice in the same month?"
  2. Public transport delay analysis. Load an open GTFS feed or any published timetable plus actuals. Produce average delay by route and hour, with a window function that flags each route's worst hour. What the interviewer asks: "what is the grain of your fact table, and what did you do with missing arrivals?"
  3. Your own expenses. Export 24 months of bank statements to CSV, categorise with CASE and a lookup table, then produce month-over-month change by category with LAG. What the interviewer asks: "how did you categorise the 8% that did not match any rule?" Have an answer, because that 8% is the whole point.

Write a README that states, in one line before each query, the question it answers. Reviewers read that README and little else, and a repo of unexplained .sql files reads as homework. Also read: 20 SQL interview questions with model answers, which map almost exactly onto weeks 3 and 7.

Week 8: add an index and read the plan

Finish by making one query faster, so you can say something concrete when asked about performance:

-- before
EXPLAIN ANALYZE SELECT * FROM orders WHERE city = 'Pune';
-- Seq Scan on orders  (cost=0.00..3214.98 rows=1402 width=64)
--   Filter: (city = 'Pune'::text)

CREATE INDEX idx_orders_city ON orders (city);
ANALYZE orders;

-- after
EXPLAIN ANALYZE SELECT * FROM orders WHERE city = 'Pune';
-- Bitmap Heap Scan on orders  (cost=32.11..812.44 rows=1402 width=64)
--   Recheck Cond: (city = 'Pune'::text)
--   ->  Bitmap Index Scan on idx_orders_city

The numbers you see will differ. What matters is that you can describe the change from a sequential scan to an index scan and explain why an index on a column with three distinct values would not have helped. If you want this on a current engine, note that PostgreSQL 18, released on 25 September 2025, turns data checksums on by default and adds a built-in uuidv7() function, and that postgresql.org's news page shows PostgreSQL 19 reaching release candidate 1 on 15 October 2026 with general availability targeted for 19 November 2026. If your workplace is still on PostgreSQL 14, flag it: the project's own schedule has that branch stopping fixes on 12 November 2026.

Where SQL Takes You Next

By week 8 our Pune analyst can answer questions nobody else on the team can answer without a BI licence, which is a real change in standing. Three routes open from there. The analyst route adds Power BI and DAX, which is what the PL-300 aligned Data Analyst program is built around. The engineering route adds pipelines and warehouse design, where DP-700 and Microsoft Fabric sit. The third is newer: systems that generate SQL still need someone who can tell when the generated query is wrong, which is a large part of RAG and AI agent engineering work, and AWS architecture work turns on choosing between RDS, Aurora and Athena by query pattern. The full certifications overview shows how they line up.

In your position I would not try to choose that route now. I would do the eight weeks, ship one project, and let the work tell me which part I actually enjoyed, because almost nobody picks correctly from the outside. Then sit in on a free webinar or a demo class on whichever route still looks interesting, and spend money only after that. Eight weeks and one honest project is a far better filter than any amount of reading about careers.

Frequently asked questions

How long does it take to learn SQL from scratch?

About 60 hours of hands-on querying, which is eight weeks at 8 hours a week, gets you to the level analyst job descriptions describe: joins, aggregation, CTEs and window functions. Reading syntax is faster than that. Being trusted with a number is not.

How to learn SQL for a data analyst job without any coding background?

SQL is the friendliest place to start precisely because there are no loops, no classes and no environment to configure. Load a CSV into SQLite, answer ten questions about it in week 1, and treat every wrong answer as the lesson. No prior programming is needed.

Should I learn MySQL or PostgreSQL first?

PostgreSQL, if you must pick one, because its window function and CTE support is the most complete and its error messages teach you the most. But start in SQLite for the first five weeks, then move to PostgreSQL in week 6 when types and EXPLAIN start to matter.

Is SQL enough to get a job in 2026?

Rarely on its own. Analyst postings pair SQL with Power BI or Tableau, Excel, and basic Python. Treat SQL as the thing that gets your CV read and the BI tool as the thing that gets you shortlisted.

What are the most important SQL topics for interviews?

Joins and their effect on row counts, GROUP BY with HAVING, CTEs, and window functions: ROW_NUMBER with PARTITION BY, LAG, and running totals. A second-round question about NULL handling or duplicate rows is close to guaranteed.

Do I need to learn SQL if AI can write queries now?

Yes, and arguably more than before. A model will happily produce a join that doubles your revenue total and present it confidently. Someone has to read the query, check the grain and sign off on the number, and that person needs to know SQL.

What free datasets should I practise SQL on?

Anything with at least two related tables. Public transport timetables, government open data portals, and your own bank statements all work. Avoid single-table toy datasets, because they teach nothing about joins, which is where the real difficulty sits.

Can I learn SQL and Power BI at the same time?

Better to stagger them. Get through week 3 of this plan, joins and grain, before you start building visuals, otherwise you will build dashboards on top of inflated numbers and not know why the totals look high.

About this guide. 360 Digital Transformation is an Anthropic Partner and a Microsoft Authorized Training Partner. Other certification bodies, vendors and employers named here are not affiliated with us. Tools and versions change quickly; commands and figures cited were checked on 2 November 2026.

Learn it live with 360 Digital Transformation

Turn this guide into a skill employers can see

Live weekend cohortEMI available

Data Analyst Course: Excel, SQL, Python & Power BI (PL-300)

Rs. 24,999

Tools and platforms you work with

  • Microsoft Excel
  • PostgreSQL
  • MySQL
  • Python
  • pandas
  • NumPy
  • matplotlib and seaborn
  • Jupyter
Add bonus modules
See the syllabus and batch dates

Other live courses on this career path