SQL Practice — Create Tables, Insert Data, and Query
SQL Practice — Create Tables, Insert Data, and Query
🎯 By the end of this lesson
After reading this lesson, you will be able to confidently do the following three things.
- ▸✅ Write a real schema using CREATE TABLE + FK + constraints
- ▸✅ Spot the pitfall of missing WHERE in INSERT · UPDATE · DELETE
- ▸✅ Combine subquery IN vs EXISTS + GROUP BY + HAVING
Keep the learning objectives as a checklist, and close the lesson once you can answer them all.
Creating Tables — CREATE TABLE + Constraints
The Starting Point of DDL
The 5 Constraints
- ▸PRIMARY KEY — Unique + NOT NULL. Row identifier. Only one per table.
- ▸NOT NULL — Cannot be empty.
- ▸UNIQUE — No duplicates allowed. Unlike PK, multiple are permitted.
- ▸CHECK — Validates value range.
CHECK (age >= 0). - ▸FOREIGN KEY — References another table. Ensures referential integrity.
Foreign Key — Building Relationships
ON DELETE CASCADE — When a parent row is deleted, child rows are automatically deleted too. With RESTRICT (the default), deleting a parent is refused if children exist.
INSERT · UPDATE · DELETE
An UPDATE/DELETE without WHERE targets every row. Accidentally omitting one line wipes the entire table. Always test inside a transaction.
JOIN — The Difference Between INNER and LEFT
Test Data
INNER JOIN — Only rows that exist on both sides
LEFT JOIN — All rows from the left table are included
Users like B who have no match are included with NULL. Commonly used for "find users with no orders":
RIGHT JOIN — Rarely used
Swapping the table order lets you express it as a LEFT JOIN. Many teams use only LEFT for consistency.
CROSS JOIN — All combinations
Cartesian product. Almost never used in production — accidentally leaving out ON produces this disaster.
Subqueries · GROUP BY · HAVING
Three Types of Subqueries
IN — Is it in the list?
EXISTS — Does at least one row match? (better performance)
EXISTS stops as soon as the first matching row is found → often faster than IN on large tables.
Scalar Subquery — returns exactly one value
Executes once per row in the SELECT clause — except on small tables, rewriting as a JOIN is faster.
GROUP BY — Pairs with aggregate functions
Using a column in SELECT that is not in GROUP BY causes an error (or non-standard behavior). The 5 aggregate functions:
- ▸
COUNT(*)— row count - ▸
SUM(col)— sum - ▸
AVG(col)— average - ▸
MAX(col)/MIN(col)— maximum / minimum
HAVING vs WHERE
WHERE filters before groups are formed, HAVING filters after groups are formed.
The key difference is that HAVING can use aggregate functions. You cannot use SUM() in WHERE.
ORDER BY · LIMIT
Fetches page 3 data (10 items per page). The fundamental pattern for pagination.
Putting It All Together — Top 5 Users
JOIN + GROUP BY + HAVING + ORDER BY + LIMIT — 90% of real-world queries use exactly this combination.
🤖 Try asking AI like this
Once you understand the concepts in this lesson, you can give AI specific instructions. Instead of a vague "fix this," you can make requests with vocabulary — and that is where token savings begin.
- ▸"Design 3 tables — users, orders, products — including FK and INDEX"
- ▸"Write a query to aggregate the number of users who signed up in the last 7 days, grouped by day"
- ▸"Add EXPLAIN to this query and interpret the execution plan"
Why This Reduces Tokens
When you don't know the concepts, you have to ask "what does that mean?" again after every AI response. Those follow-up questions eat up your tokens. Learn the concepts once and the conversation ends in one round.