Data & BI 10 min read

Learn SQL in 30 Days: A Day-by-Day Plan with Free Tools, a Practice Dataset and a Final Project

You can learn enough SQL for an analyst interview in a month if you practise every day on real questions. This plan gives you the tools, a small dataset, a task for each day and a project to finish with.

A 30-day plan to learn SQL for data analysis
Quick answer: You can learn working SQL in 30 days at about 1 to 1.5 hours a day: week 1 on SELECT, filtering and sorting; week 2 on GROUP BY and joins; week 3 on subqueries, CTEs and date functions; week 4 on window functions and a final analysis project. Every tool you need is free, including SQLite with DB Browser for SQLite, PostgreSQL and the BigQuery sandbox, which needs no credit card. The key is writing queries daily against one dataset you understand, not watching videos.

Can you really learn SQL in 30 days?

Yes, if "learn" means you can answer business questions with SELECT, GROUP BY, joins, CTEs and basic window functions. That is the level most data analyst screening tests check. It will not make you a database administrator, and fluency keeps growing for months after.

The plan below assumes about 1 to 1.5 hours a day, six days a week, with day 7 of each week kept for review. If you have less time, stretch it to 45 days rather than skipping days. Consistency matters more than long weekend sessions.

If you are still deciding whether to take a course instead, our guide on how to choose a SQL course in India compares free and paid options.

Which free tools do you need to learn SQL?

You need one place to run queries. Pick one and stay with it for the full 30 days. The core SQL you learn works across all of them, with small differences in date functions.

ToolCost (checked September 2026)Good forWatch out for
SQLite + DB Browser for SQLiteFree, open sourceFastest setup on Windows, macOS or Linux; one file holds the whole databaseDate functions differ from PostgreSQL (strftime instead of DATE_TRUNC)
PostgreSQLFree, open source (PostgreSQL License)The same engine many companies run; closest to job workInstallation takes longer; use pgAdmin or DBeaver as the editor
Google BigQuery sandboxFree, no credit card; 10 GiB storage and 1 TiB of queries a monthQuerying large public datasets in the browserTables expire after 60 days in the sandbox
Kaggle Learn (Intro to SQL, Advanced SQL)FreeShort guided lessons with exercisesUses BigQuery syntax; add your own practice alongside

Our suggestion for most beginners: SQLite with DB Browser for SQLite for weeks 1 to 3, then try the same queries in PostgreSQL or BigQuery in week 4. SQLite has supported window functions since version 3.25.0, so every query in this plan runs on it.

What practice dataset should you use?

Use a small dataset first, so you can check every answer by eye. The script below creates an online shop with 8 customers and 14 orders. Paste it into the "Execute SQL" tab of DB Browser for SQLite (or psql) and run it once.

CREATE TABLE customers (
  customer_id INTEGER PRIMARY KEY,
  name        TEXT,
  city        TEXT,
  signup_date TEXT
);
CREATE TABLE orders (
  order_id    INTEGER PRIMARY KEY,
  customer_id INTEGER,
  order_date  TEXT,
  category    TEXT,
  amount      INTEGER,
  status      TEXT
);
INSERT INTO customers VALUES
(1,'Aarav','Bengaluru','2026-01-05'), (2,'Diya','Mumbai','2026-01-12'),
(3,'Kabir','Pune','2026-01-20'),      (4,'Meera','Bengaluru','2026-02-03'),
(5,'Rohan','Delhi','2026-02-14'),     (6,'Sana','Mumbai','2026-02-25'),
(7,'Vikram','Pune','2026-03-02'),     (8,'Isha','Delhi','2026-03-18');
INSERT INTO orders VALUES
(101,1,'2026-01-06','Electronics',4500,'delivered'),
(102,2,'2026-01-15','Fashion',1200,'delivered'),
(103,1,'2026-01-28','Grocery',800,'delivered'),
(104,3,'2026-02-02','Electronics',6200,'returned'),
(105,4,'2026-02-05','Fashion',2100,'delivered'),
(106,2,'2026-02-10','Grocery',650,'delivered'),
(107,5,'2026-02-16','Electronics',3900,'delivered'),
(108,1,'2026-02-20','Fashion',1500,'delivered'),
(109,6,'2026-03-01','Grocery',900,'cancelled'),
(110,4,'2026-03-04','Electronics',5200,'delivered'),
(111,7,'2026-03-05','Fashion',1800,'delivered'),
(112,5,'2026-03-12','Grocery',700,'delivered'),
(113,2,'2026-03-20','Electronics',7400,'delivered'),
(114,3,'2026-03-25','Grocery',550,'delivered');

The names and numbers are made up for practice. From week 3 onwards, add a bigger public dataset too, such as an e-commerce or sales dataset from Kaggle, or a BigQuery public dataset. Real data brings nulls, duplicates and odd dates, which is where most learning happens.

Week 1 (days 1–7): How do you read data with SELECT?

DayTopicTask on the shop data
1Set up tool; SELECT, FROM, LIMITCreate the tables; show the first 5 orders
2WHERE with =, >, <, AND, ORList delivered orders above ₹3,000
3IN, BETWEEN, LIKEOrders in Fashion or Grocery placed in February
4ORDER BY, DISTINCT, aliasesList each city once, alphabetically
5NULL, IS NULL, COALESCEInsert an order with no category and find it
6Calculated columns and CASE WHENLabel orders as "high" (≥ ₹3,000) or "low"
7ReviewSolve 10 easy problems on HackerRank or SQLBolt without notes

Day 2 on the sample data looks like this:

SELECT order_id, customer_id, amount
FROM orders
WHERE status = 'delivered' AND amount > 3000
ORDER BY amount DESC;

Expected output: 4 rows, orders 113 (₹7,400), 110 (₹5,200), 101 (₹4,500) and 107 (₹3,900). Order 104 is ₹6,200 but was returned, so it is correctly left out.

Week 1 milestone: you can filter and sort any single table and explain each line of your query.

Explore your next step

Want feedback on your SQL, not just answers?

The ISS Data & Business Intelligence program spends weeks 3 and 4 on SQL, from PostgreSQL basics to joins, CTEs, window functions and cohort analysis, with live weekend sessions. Compare it with this self-study plan, and grab the free Data Analyst Starter Kit on this page for project briefs and interview questions.

View Data & Business Intelligence curriculum →

Week 2 (days 8–14): How do GROUP BY and joins work?

This is the week that turns lists into answers. Most business questions are "how many" or "how much" by some group, and most real data sits in more than one table.

DayTopicTask on the shop data
8COUNT, SUM, AVG, MIN, MAXAverage order value of delivered orders (answer: ₹2,525 over 12 orders)
9GROUP BYOrders and revenue by category
10HAVING vs WHERECategories with more than 4 orders
11INNER JOINDelivered revenue by city
12LEFT JOIN and finding missing rowsCustomers who never ordered
13Joins that duplicate rows; counting correctlyCompare COUNT(*) and COUNT(DISTINCT customer_id)
14Review10 medium problems; write down every mistake

Day 11, delivered revenue by city:

SELECT c.city,
       COUNT(o.order_id) AS orders,
       SUM(o.amount)     AS revenue
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
WHERE o.status = 'delivered'
GROUP BY c.city
ORDER BY revenue DESC;

Expected output:

cityordersrevenue
Bengaluru514100
Mumbai39250
Delhi24600
Pune22350

Day 12 uses a LEFT JOIN to find customers with no orders at all. On this data it returns one row: Isha from Delhi.

SELECT c.name, c.city
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
WHERE o.order_id IS NULL;

If joins feel shaky, read our SQL joins explained guide before moving on. Week 2 milestone: you can build a summary table from two joined tables and check that the row count makes sense.

Week 3 (days 15–21): When do you use subqueries, CTEs and dates?

DayTopicTask
15Subqueries in WHEREOrders above the average order value
16Subqueries in FROMRevenue per customer, then the average of that
17CTEs with WITHRewrite day 16 as a CTE and compare readability
18Date functionsMonthly delivered revenue (strftime('%Y-%m', …) in SQLite, DATE_TRUNC in PostgreSQL)
19String functions and cleaningTrim, upper-case and fix messy city names in a public dataset
20Load a bigger public datasetImport a CSV and profile it: rows, nulls, duplicates, date range
21ReviewAnswer 5 questions of your own on the bigger dataset

A CTE for repeat-purchase rate shows why CTEs matter. Each step has a name, so a reviewer can follow it:

WITH per_customer AS (
  SELECT customer_id, COUNT(*) AS delivered_orders
  FROM orders
  WHERE status = 'delivered'
  GROUP BY customer_id
)
SELECT COUNT(*) AS buyers,
       SUM(CASE WHEN delivered_orders >= 2 THEN 1 ELSE 0 END) AS repeat_buyers,
       ROUND(100.0 * SUM(CASE WHEN delivered_orders >= 2 THEN 1 ELSE 0 END)
             / COUNT(*), 1) AS repeat_rate_pct
FROM per_customer;

Expected output: 6 buyers, 4 repeat buyers, a repeat rate of 66.7%. Note the 100.0: with plain 100, integer division in SQLite and PostgreSQL would give the wrong answer.

Week 3 milestone: you can break a question into named steps and produce a monthly trend from raw dates.

Week 4 (days 22–30): How do window functions help, and what is the final project?

DayTopicTask
22ROW_NUMBER and PARTITION BYEach customer's first order
23RANK and DENSE_RANKTop category by revenue in each city
24LAG and LEADMonth-on-month revenue growth
25Running totalsCumulative revenue by date
26–29Final projectSee the brief below
30Write-up and mock testPublish the project; take a timed 30-minute test

Day 24, month-on-month growth with LAG:

WITH monthly AS (
  SELECT strftime('%Y-%m', order_date) AS month,
         SUM(amount) AS revenue
  FROM orders
  WHERE status = 'delivered'
  GROUP BY month
)
SELECT month,
       revenue,
       LAG(revenue) OVER (ORDER BY month) AS prev_revenue,
       ROUND(100.0 * (revenue - LAG(revenue) OVER (ORDER BY month))
             / LAG(revenue) OVER (ORDER BY month), 1) AS growth_pct
FROM monthly;

Expected output:

monthrevenueprev_revenuegrowth_pct
2026-016500NULLNULL
2026-028150650025.4
2026-0315650815092.0

In PostgreSQL, replace the strftime line with TO_CHAR(order_date::date, 'YYYY-MM'). The window part is identical.

What should the final SQL project look like?

Pick a public sales or e-commerce dataset with at least a few thousand rows and a date column. Then answer one business question end to end, for example: "Which customer segment should the marketing team focus on next quarter?"

  1. Profile the data: row counts, date range, nulls and duplicates, with the queries you used.
  2. Core metrics: monthly revenue, orders, average order value and repeat rate.
  3. Segments: the same metrics by city, category or customer type.
  4. One window-function insight: first-order category, month-on-month growth or top products per segment.
  5. Recommendation: three sentences on what the business should do, and what you would check next.

Put the queries in a GitHub repository with a short README that leads with the finding, not the code. Our guide to data analyst resume projects shows how to frame it for a recruiter.

What mistakes slow people down when learning SQL?

  • Watching, not typing. Type every query yourself, even when you could copy it.
  • Not checking row counts. After every join, check whether the number of rows went up unexpectedly.
  • Filtering aggregates with WHERE. Use HAVING for conditions on SUM or COUNT.
  • Ignoring NULLs. COUNT(column) skips NULLs; COUNT(*) does not.
  • Switching tools every week. Pick one database and finish the plan in it.
  • Only solving puzzles. Practice sites are useful for speed, but interviews also ask you to explain what a result means for the business.

When you finish, test yourself against our list of SQL interview questions and the wider data analytics interview questions guide. For where SQL fits among Excel, BI tools and Python, see the data analyst roadmap.

Frequently Asked Questions

Can I learn SQL in 30 days with no coding background?

Yes. SQL reads close to plain English, and this plan starts from SELECT. At 1 to 1.5 hours a day, most beginners can reach joins, CTEs and basic window functions in 30 days. Expect to keep practising afterwards to get fast.

Which free tool should I use to learn SQL?

For most beginners, SQLite with DB Browser for SQLite is the quickest to set up, and it is free and open source. PostgreSQL is closer to what many companies run. The BigQuery sandbox is free without a credit card and suits large public datasets.

Is SQL enough to get a data analyst job?

Usually not on its own. Most analyst roles also ask for Excel, a BI tool such as Power BI or Tableau, and the ability to explain findings. SQL is the foundation that most screening tests check first.

Should I learn MySQL or PostgreSQL first?

Either is fine. SELECT, JOIN, GROUP BY, CTEs and window functions work the same way in both. Differences are mostly in date and string functions, which take a few days to adjust to.

How many hours a day should I practise SQL?

About 1 to 1.5 hours a day, six days a week, is enough for this plan. If you have less time, stretch the plan to 45 days instead of skipping topics.

What should I do after the 30 days?

Keep solving two or three problems a day, redo your final project on a larger dataset, and add a BI tool such as Power BI so you can present your SQL results as a dashboard.

Sources and methodology

Tool costs and limits were checked on official pages in September 2026.

The shop dataset is made up for practice. Every query and expected output shown was run on it in SQLite 3.54 before publishing. The 30-day schedule and time estimates are ISS editorial guidance, not a provider's figures.

Next steps

Start day 1 today: install DB Browser for SQLite, paste the dataset script and run your first SELECT. If you would rather learn SQL alongside Excel, Python and dashboards in a live 16-week cohort, review the Data & Business Intelligence curriculum.

Applying is free, and you pay only after accepting an offer. Apply here.

Get SQL practice problems by email

Occasional emails with practice questions, study plans and honest guides for data careers in India.