SQL for Data Engineering
Learn the SQL data engineers write daily: joins, aggregation, window functions, CTEs, upserts, query plans, and validation checks on real tables.
What You'll Learn
Why SQL Is the Skill That Never Leaves Your Desk
You have just joined acme-shop's data team. The first pipeline script is written in Python.
Creating and Changing Tables - DDL and DML Basics
Before querying tables, it helps to know how they come to exist and how they change.
Primary Keys, Foreign Keys, and Constraints
Constraints let the database refuse bad data at the door, so you do not have to find it later.
SELECT, FROM, WHERE - The Query Every Other Query Builds On
Every query starts from the same three clauses. SELECT names the columns, FROM names the table, and WHERE filters which rows qualify.
CASE WHEN - Conditional Logic Inside a Query
CASE WHEN makes a decision per row, like if/elif/else in Python, but as an expression that produces a column value.
JOINs - Connecting Tables the Way Real Data Is Split
Production data is split across tables. A JOIN combines rows from two tables on a matching column.
Skills You'll Master
Curriculum Index18 topics
Why SQL Is the Skill That Never Leaves Your Desk
You have just joined acme-shop's data team. The first pipeline script is written in Python.
Creating and Changing Tables - DDL and DML Basics
Before querying tables, it helps to know how they come to exist and how they change.
Primary Keys, Foreign Keys, and Constraints
Constraints let the database refuse bad data at the door, so you do not have to find it later.
SELECT, FROM, WHERE - The Query Every Other Query Builds On
Every query starts from the same three clauses.
CASE WHEN - Conditional Logic Inside a Query
CASE WHEN makes a decision per row, like if/elif/else in Python, but as an expression that produces a column value.
JOINs - Connecting Tables the Way Real Data Is Split
Production data is split across tables. A JOIN combines rows from two tables on a matching column.
SQL Execution Order - Why WHERE, HAVING, and Aliases Behave the Way They Do
A query is read top to bottom, but it does not run that way.
Window Functions - The Skill Every Interview Tests
GROUP BY collapses many rows into one row per group.
CTEs and Subqueries - Writing SQL a Teammate Can Actually Read
A CTE (Common Table Expression) is a named, temporary result defined with WITH and used inside a larger query.
Date and Time in SQL
Pipeline queries filter by date constantly, so handling dates correctly in SQL matters.
Set Operations - Combining Query Results Vertically
A JOIN combines tables side by side. A set operation stacks the results of two queries.
Performance and Reading a Query Plan
A query that returns correct results but takes four minutes on a large table is not working in production.
SQL for Data Validation - The Queries You Will Write Every Day
Before any transformation or dashboard trusts a table, someone checks that it looks right.
Transactions (Good to Know)
A transaction groups operations so they either all succeed or all roll back. There is no half-changed state in between.
Troubleshooting Scenario - Find and Fix the Broken Query
A teammate wants products with more than 600 units sold in total.
Hands-On Lab
📌 Remember: This lab is free and runs on your laptop with Docker, Python, and a terminal. No cloud account is needed.
Quick Reference
Syntax at a Glance Choosing Between Common Options
Common Mistakes
Using WHERE to filter on an aggregate causes an error every time, because WHERE runs before GROUP BY has produced...
Career Impact
Roles that use the skills in this module.
Data Engineer
Platform Engineer
Next Modules
Related Guides
Practice on the Coding Sheet
Not a software engineer sheet. Every problem comes from real DevOps, SRE, Platform and Cloud interviews, from your first script to a system you build yourself.
Open the Coding SheetFrequently Asked Questions
Python moves and shapes data in pipelines, but SQL is how you inspect tables, transform data inside a warehouse, and prove that results are correct. Running the aggregation where the data lives is usually faster than pulling rows into Python.
WHERE filters individual rows before grouping happens. HAVING filters groups after aggregation, so conditions on COUNT, SUM, or AVG belong there.
A window function calculates something across a set of related rows, such as a rank or a running total, but keeps every original row. GROUP BY, in contrast, collapses rows into one per group.
Pipelines get rerun after failures. An idempotent write, such as an upsert, gives the same result no matter how many times it runs, so a rerun does not create duplicates.