Introduction to SQL for Data Analytics
Why SQL is essential
Section titled “Why SQL is essential”Most analytics work happens where the data lives:
- Relational databases (PostgreSQL, MySQL, SQLite)
- Data warehouses (BigQuery, Snowflake, Redshift)
SQL is used to:
- Retrieve data efficiently
- Aggregate metrics (DAU, revenue, churn)
- Join multiple tables (users + orders + events)
Core mental model
Section titled “Core mental model”- Data is stored in tables.
- A query reads rows/columns and returns a result set.
SELECT *
FROM users
LIMIT 10;Typical analytics tables
Section titled “Typical analytics tables”users(user_id, created_at, country, plan)orders(order_id, user_id, order_ts, amount)events(user_id, event_ts, event_name, device)
What you’ll learn in this phase
Section titled “What you’ll learn in this phase”SELECT,WHERE,ORDER BY,LIMIT- Aggregations:
COUNT,SUM,AVG GROUP BY,HAVING- Joins
- Window functions
- CTEs
- Using SQL from Python (pandas)
Where SQL fits in an analytics workflow
Section titled “Where SQL fits in an analytics workflow”You rarely run one query in isolation. The usual shape of the work is: raw tables live in a database, a query filters and reshapes them, and the result lands somewhere you can chart, model, or share.
flowchart LR A["users table"] --> D["SQL query"] B["orders table"] --> D C["events table"] --> D D --> E["Result set (rows + columns)"] E --> F["pandas DataFrame / BI dashboard"]
The database never changes because you queried it — a SELECT just reads and returns rows.
That’s what makes SQL safe to explore with: you can run the same query a hundred times while
you’re figuring out the right filter, and nothing gets damaged.
SQLite: a database in a single file
Section titled “SQLite: a database in a single file”You don’t need a server to practice SQL. SQLite (Python’s built-in sqlite3 module) stores an
entire database in one file — or even in memory — which makes it perfect for learning and for
the exercises on this page.
import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE users (user_id INTEGER, country TEXT, plan TEXT)")
conn.executemany(
"INSERT INTO users VALUES (?, ?, ?)",
[(1, "IN", "free"), (2, "IN", "pro"), (3, "US", "pro")],
)
conn.commit()
rows = conn.execute("SELECT * FROM users").fetchall()
print(rows)[(1, 'IN', 'free'), (2, 'IN', 'pro'), (3, 'US', 'pro')]🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Create a table and read it back
Section titled “Exercise 1 – Create a table and read it back”Exercise 2 – Filter rows with WHERE
Section titled “Exercise 2 – Filter rows with WHERE”Exercise 3 – Load a query result into pandas
Section titled “Exercise 3 – Load a query result into pandas”Head to SQL Basics (SELECT, WHERE, ORDER BY, LIMIT) to practice the four clauses you’ll use in almost every query you ever write.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading