SQL Essentials — RDBMS · SELECT · WHERE · GROUP BY · JOIN
SQL Essentials — RDBMS · SELECT · WHERE · GROUP BY · JOIN
🎯 By the end of this lesson
After reading this lesson, you will be able to confidently do the following three things.
- ▸✅ Use SELECT · WHERE · GROUP BY · HAVING · ORDER BY clauses in the correct order
- ▸✅ Understand the difference between INNER JOIN and LEFT JOIN, and choose the right one
- ▸✅ Read a query execution plan using EXPLAIN (the
typeandrowscolumns)
Keep these learning goals as a checklist, and close the lesson once you can answer all of them.
6 Core RDBMS Concepts
In one line: Relational DB = table + PK/FK + normalization + ACID + index + SQL. A 50-year standard.
6 Key Concepts
Quick Guide to Normalization Levels
> 💡 In practice: 3NF is typically sufficient. Intentional denormalization is applied for performance in frequently queried areas.
SQL 4 Parts
SELECT: 7 Clauses and Their Execution Order
Writing Order vs. Execution Order
Each Clause — Role and Common Pitfalls
Quick Memorization Tip
- ▸FWG·HSO·L — From-Where-Group / Having-Select-Order / Limit
- ▸Reduce data early — the earlier WHERE runs, the lighter the subsequent steps
- ▸5 patterns that skip the index: functions, LIKE with leading %, type casting, NOT, OR
JOIN + GROUP BY Patterns
Comparing 5 JOIN Types
JOIN Anti-Patterns
Anti-join (rows that exist on one side only):
Self-join (self-referencing):
6 GROUP BY Patterns
WHERE vs. HAVING
💾 Practice 1 — Order Statistics per User (LEFT JOIN + GROUP BY)
-- Input: users table + orders table
-- Process: LEFT JOIN to include users with no orders + GROUP BY to aggregate per user
-- Output: order count and total payment amount per user (0 for users with 0 orders)
SELECT
u.id,
u.name,
COUNT(o.id) AS order_count, -- number of orders
COALESCE(SUM(o.amount), 0) AS total -- total payment amount (NULL → 0)
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id
AND o.status = 'PAID' -- completed payments only
GROUP BY u.id, u.name
ORDER BY total DESC
LIMIT 5;
💾 Practice 2 — Monthly Revenue (DATE_TRUNC + HAVING)
-- Input: orders (created_at, total, status)
-- Process: group by month + filter for completed payments + only months with 1,000,000 or more
-- Output: order count and revenue per month
SELECT
DATE_TRUNC('month', created_at)::DATE AS month,
COUNT(*) AS orders,
SUM(total) AS revenue,
ROUND(AVG(total)) AS avg_order
FROM orders
WHERE status = 'PAID'
GROUP BY month
HAVING SUM(total) > 1000000
ORDER BY month;
💾 Practice 3 — Window Functions (Top 3 Recent Orders per User)
-- Input: orders
-- Process: sort per user via PARTITION BY user_id → top 3
-- Output: the 3 most recent orders for each user
WITH ranked AS (
SELECT
o.*,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY created_at DESC
) AS rn
FROM orders o
)
SELECT user_id, id AS order_id, total, created_at
FROM ranked
WHERE rn <= 3
ORDER BY user_id, rn;
EXPLAIN — Reading Query Execution Plans
Why You Need EXPLAIN
Two queries that return the same result can differ in speed by tens or hundreds of times depending on how the database executes them internally. EXPLAIN shows you the decisions made by the MySQL optimizer.
Usage
Result:
The Most Important Columns — type and rows
type levels — best to worst
1. const / system — exactly 1 row (PK lookup). Best.
2. eq_ref — PK or UNIQUE index used in a JOIN. Very good.
3. ref — index used. Good.
4. range — range index scan (WHERE age > 20). Acceptable.
5. index — full index scan. Bad.
6. ALL — full table scan. Worst — no index in use.
If type shows ALL, add an index or rewrite the query.
rows — estimated number of rows to examine
On a table with 1 million rows, rows: 1000000 means a full scan. rows: 5 means the index was hit. Fewer rows = faster.
EXPLAIN ANALYZE — Including Actual Execution Time (MySQL 8+)
Executes the query and prints the actual time spent at each step. The essential tool for debugging slow queries.
Practical Workflow
1. Collect queries taking over 1 second from the slow query log (slow_query_log)
2. Run EXPLAIN on each query
3. Queries with type=ALL or large rows → consider adding an index
4. Use EXPLAIN ANALYZE to compare before and after the improvement
🤖 Try asking AI like this
Knowing the concepts in this lesson lets you give specific instructions to AI. Instead of a vague 'fix this,' you can make requests with vocabulary — and that's where token savings begin.
- ▸'Design a 3-table schema for users · orders · products, complete with FK and INDEX'
- ▸'Write a query that aggregates the number of users who signed up in the last 7 days, broken down by day'
- ▸'Add EXPLAIN to this query and interpret the execution plan'
Why This Reduces Tokens
Without knowing the concepts, even after receiving an AI answer, you have to ask 'what does that mean?' again. That follow-up question is what burns tokens. Learn the concepts once, and the conversation ends in a single exchange.