Data Basics · SQL for Beginners
SQL Tutorial for Beginners 2026
Quick summary — SQL for beginners
SQL is the most in-demand skill in data careers — and one of the fastest to learn. This guide walks you through the fundamentals in 6 weeks: SELECT, filtering, JOINs, aggregations, subqueries, and window functions — with hands-on practice.
In this guide you will learn:
- Level 1: Basics — SELECT, WHERE, ORDER BY, LIMIT.
- Level 2: Joins + Aggregations — INNER/LEFT JOINs, GROUP BY, HAVING.
- Level 3: Advanced — subqueries, CTEs, window functions.
- Real practice — where to practice SQL for free.
- Common mistakes — what to avoid as a beginner.
SECTION 01Level 1: SELECT, WHERE, ORDER BY (Week 1-2)
The first two weeks build the foundation every SQL query needs. Here's the breakdown:
| Week | Focus | Daily Actions | Weekly Goal |
|---|---|---|---|
| Week 1 | SELECT basics | SELECT, column aliases, DISTINCT, LIMIT | Read data from 3 tables |
| Week 2 | Filtering + sorting | WHERE, AND/OR, IN, BETWEEN, LIKE, ORDER BY | Solve 20 filtering problems |
-- Select all columns from a table
SELECT * FROM users;
-- Select specific columns
SELECT name, email FROM users;
-- Use aliases
SELECT name AS full_name, age AS years
FROM users;
-- Unique values
SELECT DISTINCT country FROM users;
-- Limit results
SELECT * FROM users LIMIT 10;
-- Common beginner dataset:
-- users (id, name, email, country, age)
-- orders (id, user_id, amount, status, created_at)
-- products (id, name, price, category)
-- Basic WHERE
SELECT * FROM users WHERE country = 'India';
-- Multiple conditions
SELECT * FROM users
WHERE country = 'India' AND age > 25;
-- IN for a list of values
SELECT * FROM users
WHERE country IN ('India', 'USA', 'UK');
-- BETWEEN for a range
SELECT * FROM orders
WHERE amount BETWEEN 100 AND 500;
-- LIKE for pattern matching
SELECT * FROM users WHERE name LIKE 'A%'; -- starts with A
SELECT * FROM users WHERE name LIKE '%a'; -- ends with a
SELECT * FROM users WHERE name LIKE '%ok%'; -- contains ok
-- Sorting (default ASC)
SELECT name, age FROM users ORDER BY age DESC;
-- Multiple sort keys
SELECT * FROM users ORDER BY country ASC, age DESC;
-- Combine filter + sort + limit
SELECT name, age FROM users
WHERE country = 'India'
ORDER BY age DESC
LIMIT 5;
SECTION 02Level 2: JOINs + GROUP BY (Week 3-4)
The second phase is where SQL gets interesting — combining tables and summarizing data. Here's the plan:
| Week | Focus | Daily Actions | Weekly Goal |
|---|---|---|---|
| Week 3 | JOINs | INNER, LEFT, RIGHT, FULL OUTER joins | Write 15 JOIN queries |
| Week 4 | Aggregations | COUNT, SUM, AVG, MIN, MAX, GROUP BY, HAVING | Solve 20 aggregation problems |
-- INNER JOIN (only matching rows)
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON o.user_id = u.id;
-- LEFT JOIN (all users, plus matching orders)
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;
-- Find users with no orders
SELECT u.name
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;
-- Multiple JOINs
SELECT u.name, o.amount, p.name AS product
FROM users u
JOIN orders o ON o.user_id = u.id
JOIN products p ON p.id = o.product_id;
-- Self-join (employees + managers)
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
-- Count rows
SELECT COUNT(*) FROM users;
-- Sum + average
SELECT SUM(amount) AS total, AVG(amount) AS avg
FROM orders;
-- Group by one column
SELECT country, COUNT(*) AS user_count
FROM users
GROUP BY country;
-- Group by with filter inside
SELECT status, SUM(amount) AS revenue
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY status;
-- HAVING filters grouped results
SELECT country, COUNT(*) AS user_count
FROM users
GROUP BY country
HAVING COUNT(*) > 100;
-- Group + join combo (super common)
SELECT u.country, SUM(o.amount) AS revenue
FROM users u
JOIN orders o ON o.user_id = u.id
GROUP BY u.country
ORDER BY revenue DESC;
-- Remember:
-- WHERE → filters rows before grouping
-- HAVING → filters groups after aggregation
SECTION 03Level 3: Subqueries, CTEs, Window Functions (Week 5-6)
The third phase takes you into real analyst territory — advanced queries and window functions. Here's the plan:
| Week | Focus | Daily Actions | Weekly Goal |
|---|---|---|---|
| Week 5 | Subqueries + CTEs | Scalar, correlated subqueries, WITH clauses | Rewrite 10 queries with CTEs |
| Week 6 | Window Functions | ROW_NUMBER, RANK, LAG, LEAD, running totals | Solve 10 window problems |
-- Scalar subquery (single value)
SELECT name FROM users
WHERE age > (SELECT AVG(age) FROM users);
-- Subquery in FROM
SELECT country, avg_age
FROM (
SELECT country, AVG(age) AS avg_age
FROM users
GROUP BY country
) AS country_stats
WHERE avg_age > 30;
-- CTE (Common Table Expression) — readable alternative
WITH country_stats AS (
SELECT country, AVG(age) AS avg_age
FROM users
GROUP BY country
)
SELECT * FROM country_stats WHERE avg_age > 30;
-- Multiple CTEs
WITH active_users AS (
SELECT * FROM users WHERE status = 'active'
),
user_revenue AS (
SELECT user_id, SUM(amount) AS revenue
FROM orders
GROUP BY user_id
)
SELECT a.name, r.revenue
FROM active_users a
JOIN user_revenue r ON r.user_id = a.id
ORDER BY r.revenue DESC;
-- Rule of thumb:
-- CTEs are the modern way to structure complex queries.
-- Prefer CTEs over nested subqueries for readability.
-- ROW_NUMBER: unique row number per partition
SELECT name, country,
ROW_NUMBER() OVER (PARTITION BY country ORDER BY age DESC) AS rn
FROM users;
-- RANK: allows ties
SELECT name, score,
RANK() OVER (ORDER BY score DESC) AS rank
FROM exam_results;
-- Get top 3 per country (super common pattern)
WITH ranked AS (
SELECT name, country, salary,
ROW_NUMBER() OVER (PARTITION BY country ORDER BY salary DESC) AS rn
FROM employees
)
SELECT * FROM ranked WHERE rn <= 3;
-- LAG: previous row's value
SELECT date, revenue,
LAG(revenue) OVER (ORDER BY date) AS prev_day_revenue
FROM daily_revenue;
-- Running total
SELECT date, revenue,
SUM(revenue) OVER (ORDER BY date) AS running_total
FROM daily_revenue;
-- Moving average (last 3 days)
SELECT date, revenue,
AVG(revenue) OVER (ORDER BY date ROWS 2 PRECEDING) AS ma_3
FROM daily_revenue;
-- Notes:
-- Window functions keep all rows (unlike GROUP BY).
-- PARTITION BY = "group by" for windows.
-- ORDER BY inside OVER = how to sequence rows.
-- These are heavily tested in data analyst interviews.
SECTION 04Practice platforms + datasets
Use these platforms to practice — free and paid:
Free SQL Practice Platforms:
1. LeetCode (Database section)
- Beginner to advanced problems
- Great for interview prep
2. SQLBolt (sqlbolt.com)
- Interactive lessons + exercises
- Perfect for absolute beginners
3. HackerRank (SQL track)
- Structured beginner track
- Certification available
4. Mode Analytics SQL Tutorial
- Real datasets, guided walkthroughs
- Focus on analytics queries
5. StrataScratch (free tier)
- Real interview questions
- Good for advanced practice
6. DB-Fiddle
- Browser-based SQL editor
- No setup — just paste and run
Public Datasets to Practice On:
1. Kaggle Datasets
- Thousands of real datasets (CSV → SQLite)
- Start with small ones (< 10k rows)
2. Google BigQuery public data
- NY taxi rides, GitHub repos, etc.
- Free tier allows real-scale practice
3. Chinook Database
- Classic example DB (music store)
- Great for JOINs + aggregations
4. Northwind Database
- Old but excellent for classic SQL practice
- Covers orders, customers, products
5. Sakila Database
- Movie rental DB with complex relationships
- Great for JOIN practice
Download CSV, load into DB, practice:
- DB Browser for SQLite (free, cross-platform)
- pgAdmin (PostgreSQL)
- MySQL Workbench
- DBeaver (any database)
Local Practice Setup (5 minutes):
Option 1: SQLite (simplest)
- Install DB Browser for SQLite
- Open a .db file
- Run queries instantly
- No server setup needed
Option 2: PostgreSQL (industry standard)
- Install PostgreSQL
- Create a database
- Load a CSV with \copy
- Practice real-world SQL
Option 3: MySQL
- Install MySQL Community Server
- Use MySQL Workbench
- Very common in production
Option 4: Cloud (no install)
- Google BigQuery (free tier)
- AWS Athena (pay per query)
- Supabase (free Postgres)
Recommendation for beginners:
- Start with SQLite (no setup)
- Move to PostgreSQL once comfortable
- Both teach the same SQL fundamentals
SECTION 05Common beginner mistakes
Here are the most common mistakes beginners make in SQL — and how to avoid them:
- Using SELECT * in production queries — always pick the columns you actually need.
- Forgetting WHERE in UPDATE/DELETE — will update/delete every row. Dangerous!
-
Confusing NULL with empty string — they're not the same.
Use
IS NULL, not= NULL. - Mixing up WHERE and HAVING — WHERE filters rows before grouping; HAVING filters after.
- Ignoring indexes — slow queries often mean missing indexes; learn EXPLAIN plans.
SECTION 06Interview Q&A — SQL basics
Q1What's the difference between WHERE and HAVING?
WHERE filters individual rows before grouping. HAVING filters groups after aggregation. You can't use aggregate functions (like COUNT or SUM) in WHERE — use HAVING for those.
Q2What's the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows where the join condition matches in both tables. LEFT JOIN returns all rows from the left table, plus matches from the right (NULL where no match). LEFT JOIN is the safer default when you want all primary records.
Q3What are window functions?
Window functions compute values across a set of rows related to the current row, without collapsing them into groups. Common examples: ROW_NUMBER, RANK, LAG, LEAD, running totals. They're essential for ranking, time-series analysis, and comparative metrics.
Q4What's a CTE?
A Common Table Expression (CTE) is a named temporary result set defined with the WITH keyword. CTEs make complex queries readable by breaking them into named steps — the modern alternative to nested subqueries.
Q5How do I know if my query is slow?
Use EXPLAIN or EXPLAIN ANALYZE (PostgreSQL) or EXPLAIN (MySQL) to see the query plan. Look for full table scans, missing indexes, and expensive joins. Adding an index on the join/filter column often fixes slow queries.
SECTION 07Test yourself — SQL quiz
Five questions. No sign-up.
0 / 5Pick an answer to see why it is right or wrong.
SECTION 08Frequently asked questions
How long does it take to learn SQL?
4-6 weeks of consistent practice is enough for a solid foundation. You'll be comfortable with SELECT, WHERE, JOINs, and GROUP BY. Window functions take another 2-3 weeks. Mastery takes longer — real projects teach most.
Do I need coding experience to learn SQL?
No — SQL is one of the most beginner-friendly languages. It reads like English ("SELECT name FROM users WHERE country = 'India'"), and you don't need a programming background to be productive.
Which SQL dialect should I learn?
The fundamentals are the same across dialects. Learn the basics with SQLite (no setup) or PostgreSQL (industry standard). The syntax transfers to MySQL, SQL Server, and BigQuery with small differences.
Is SQL enough for a data analyst job?
SQL is the foundation, but data analyst roles usually require one more skill: Excel, Power BI/Tableau, or Python. SQL + one BI tool is the standard entry-level combo.
How often should I practice SQL?
Daily practice is best — even 30-45 minutes is enough. Solving a few problems daily beats hour-long weekly sessions. Consistency beats intensity for SQL.
SECTION 09Related reads
Classroom & online · Noida
Start your SQL journey today
Our SQL + Data Analytics Course covers SQL fundamentals to advanced window functions — with real datasets and interview prep.
₹15,500 · full programme- SQL + Power BI
- Real datasets
- Interview prep
- Weekday & weekend batches