SQL Lesson 2: Pull 3 Rows From 1,000,000 in One Line
๐ Full written solution: https://interview-kit-fe.vercel.app/sql-lesson-02-select-from-where-core-querying ๐ป Code on GitHub: https://github.com/timepasshub2539-hue/leetcode-python/tree/main/sql-lesson-02-select-from-where-core-querying Chapters: 0:00 Pull 3 rows out of 1,000,000 โ in one line 0:17 What is a table, really? 0:36 Meet the users table 0:51 SELECT โ which columns? 1:07 FROM โ which table? 1:24 WHERE โ which rows? 1:41 Watch WHERE walk the rows 1:54 The order SQL actually runs 2:10 More WHERE conditions 2:28 Mistake: quotes and equals 2:45 Mistake: SELECT * 3:05 WHERE vs. filter in code 3:26 Recap: your first real query Master the three clauses behind every SQL query: SELECT (which columns), FROM (which table), and WHERE (which rows). We walk WHERE row-by-row through a users table, reveal the surprising order SQL actually executes, and fix the two mistakes everyone makes early โ quotes vs. equals and blind SELECT *. By the end you'll write your first real query that pulls 3 rows out of a million in a single line. Perfect for beginners moving from "what is a table?" to confident, filtered queries. #SQL #LearnSQL #Database #SQLForBeginners #DataAnalysis Watch next: - 74% of Women Lived. 19% of Men Didn't. The Data Explains Why: https://youtu.be/xg_LtvWLmBw - You've Used These 10 Functions Thousands of Times #shorts: https://youtu.be/oZu7t8eNNpM - Common Mistake: Forgetting Parentheses #shorts: https://youtu.be/LvqHSqyQvZk
SEO PACKAGE
1. SEO Title: SQL SELECT, FROM, and WHERE Explained: Pull 3 Rows From a Million in One Line
2. SEO Subtitle: Master the three clauses behind almost every SQL query โ and the execution order that finally makes filtering click.
3. Featured Quote:
"You write
SELECTfirst, but the database runs it last. Once you see that order, SQL stops being magic and starts being logic."
4. Meta Description: Learn SQL's SELECT, FROM, and WHERE clauses step by step. Understand the real execution order and write your first filtered query with confidence. (154 characters)
5. URL Slug:
sql-select-from-where-explained
6. Keywords: SQL, SELECT statement, FROM clause, WHERE clause, SQL for beginners, learn SQL, SQL query, filtering rows in SQL, SQL execution order, relational database, SQL tutorial, database queries, SQL basics, SQL WHERE condition, data analysis SQL, SQL AND operator, coding interview SQL, SQL best practices, SELECT star, structured query language
7. Tags: SQL, Databases, SQL for Beginners, Data Analysis, Backend Development, Coding Interview, Software Engineering, SQL Query, Relational Databases, Learn to Code, Data Engineering, SQL Tutorial, Programming Basics
SQL SELECT, FROM, and WHERE Explained: Pull 3 Rows From a Million in One Line
8. Introduction
Imagine a spreadsheet a million rows tall. Somewhere inside it are three rows you actually need. You don't want to scroll. You don't want to write a loop. You want to walk up to that mountain of data and calmly ask for the exact slice you care about โ and get it back in milliseconds.
That is what SQL is for, and you get almost all of its power from just three words: SELECT, FROM, and WHERE. These three clauses run nearly every data question asked on Earth, from a startup's first analytics dashboard to the query behind your bank statement.
If you're moving from "what is a table?" toward confident, filtered queries, this is the lesson that flips the switch. Interviewers lean on these fundamentals constantly โ not because they're hard, but because they reveal whether you actually understand how a database thinks. A candidate who knows why SELECT runs last, or why SELECT * is a lazy habit, signals real fluency. In software engineering, data structures and algorithms get the spotlight, but the ability to ask a database for precisely what you need is a skill you'll use every single working day.
Let's build that intuition from the ground up.
9. Problem Overview
Here's the challenge in plain terms: given a table full of records, return only the specific columns and only the specific rows that answer your question.
Before the vocabulary scares anyone off, let's name the furniture:
- A table is just a spreadsheet. Every row is one thing โ one customer, one order, one user. Every column is one detail about that thing โ a name, a city, an age.
- A relational database is nothing more than a collection of these neat tables sitting side by side.
So the whole job of a basic query is this: scan down the rows of a table, keep the rows that pass a test, and show back only the columns you asked for. Three clauses do this work:
| Clause | Job | Restaurant analogy |
|---|---|---|
SELECT |
Which columns come back | Ordering specific dishes off the menu |
FROM |
Which table to read | Naming the restaurant |
WHERE |
Which rows survive | The bouncer at the door |
10. Example
Let's build a tiny world we can check in our heads. Here is a users table with four rows:
| name | city | age |
|---|---|---|
| Ana | Delhi | 25 |
| Ben | Mumbai | 30 |
| Cara | Delhi | 22 |
| Dev | Pune | 40 |
Query:
SELECT name, age
FROM users
WHERE city = 'Delhi';
Result:
| name | age |
|---|---|
| Ana | 25 |
| Cara | 22 |
Read it out loud: "Give me the name and age, from users, where the city is Delhi." It's almost a plain English sentence.
Why this output? WHERE city = 'Delhi' kept only Ana and Cara. Then SELECT name, age dropped the city column, because we never asked for it. Ben and Dev never made it past the door.
11. Intuition
Here's the mental model an experienced engineer carries around, and it's the single most useful thing in this article.
The database does not run your query top to bottom.
You write SELECT first, but the engine doesn't touch it until the very end. Instead, it works in this order:
FROMโ grab the whole table. Now you're holding a million rows.WHEREโ walk down those rows and throw out every one that fails the test. Now you're holding three.SELECTโ from the survivors, keep only the columns you named.
The shape is simple: rows in โ rows filtered โ columns chosen.
Picture WHERE as a bouncer checking IDs one row at a time. The question is city = 'Delhi':
Ana โ Delhi? YES โ let in
Ben โ Delhi? no โ turned away
Cara โ Delhi? YES โ let in
Dev โ Delhi? no โ turned away
That is genuinely all a filter does โ one row, one yes-or-no question, and the survivors become your result. Once you internalize "FROM, then WHERE, then SELECT," every confusing query you'll ever meet untangles itself.
12. Brute Force Solution
Before we appreciate WHERE, let's see life without it โ the approach many programmers reach for first.
The idea: Skip filtering in SQL entirely. Pull every row into your application, then filter with a loop in Python (or whatever language you know).
The algorithm:
# Brute force: drag everything out, filter in the app
rows = db.execute("SELECT name, age, city FROM users")
result = []
for row in rows:
if row["city"] == "Delhi": # do the filtering ourselves
result.append((row["name"], row["age"]))
Advantages:
- Feels familiar if you already know a programming language.
- No new SQL syntax to learn โ the logic lives in code you control.
Disadvantages:
- You just shipped a million rows across the network to keep three. That's wasted bandwidth, memory, and time.
- The database engine โ which is built to filter data efficiently, often using indexes โ sits idle while your app does slow work it was never meant to do.
- It doesn't scale. On a real table this melts your application.
Time complexity: O(n) in your application, where n is every row in the table.
Space complexity: O(n) โ you're holding the entire table in memory.
The lesson: filter where the data lives, not after you've dragged it out.
13. Optimal Solution
The optimal approach lets WHERE do the heavy lifting, right next to the data.
SELECT name, age
FROM users
WHERE city = 'Delhi';
Step by step, here's what the engine does:
Step 1 โ FROM users: Identify the source. The engine now knows which table to scan.
Step 2 โ WHERE city = 'Delhi': Evaluate the condition against each row. On a real database with an index on city, the engine may not even scan all million rows โ it can jump straight to the matches. This is the superpower your application loop can never match.
Step 3 โ SELECT name, age: Project only the requested columns from the surviving rows.
WHERE isn't limited to equality. You can compare, and you can combine conditions with AND so both must be true:
SELECT name, age
FROM users
WHERE city = 'Delhi' AND age > 20;
Walking our table:
| name | city = 'Delhi'? | age > 20? | Both true? |
|---|---|---|---|
| Ana | โ | โ (25) | Kept |
| Ben | โ | โ | Dropped |
| Cara | โ | โ (22) | Kept |
| Dev | โ | โ | Dropped |
One rule to tattoo on your brain: text values go in single quotes, numbers stay bare. 'Delhi' needs quotes; 20 does not.
14. Python Code
Here's how you'd run this cleanly from Python using the standard sqlite3 module โ production-shaped, with a parameterized query to stay safe from SQL injection.
import sqlite3
def find_users(db_path: str, city: str, min_age: int) -> list[tuple[str, int]]:
"""Return (name, age) for users in a city above a minimum age."""
query = """
SELECT name, age
FROM users
WHERE city = ? AND age > ?
"""
with sqlite3.connect(db_path) as conn:
# Parameters passed separately โ never format them into the string.
rows = conn.execute(query, (city, min_age)).fetchall()
return rows
if __name__ == "__main__":
# Self-check on an in-memory table.
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE users (name TEXT, city TEXT, age INTEGER)")
conn.executemany(
"INSERT INTO users VALUES (?, ?, ?)",
[("Ana", "Delhi", 25), ("Ben", "Mumbai", 30),
("Cara", "Delhi", 22), ("Dev", "Pune", 40)],
)
conn.commit()
result = conn.execute(
"SELECT name, age FROM users WHERE city = ? AND age > ?",
("Delhi", 20),
).fetchall()
assert result == [("Ana", 25), ("Cara", 22)], result
print("OK:", result)
15. Code Walkthrough
query = """ ... """โ The SQL lives in a triple-quoted string so the three clauses read like the sentence they are. The?placeholders are gaps the driver fills in safely.conn.execute(query, (city, min_age))โ The values are passed as a separate tuple, not glued into the string. This is the parameterized-query habit that closes the door on SQL injection. Noticecitymaps to the first?andmin_ageto the second..fetchall()โ Pulls back the surviving rows as a list of tuples.with sqlite3.connect(...)โ The context manager commits and closes cleanly, even if something throws.- The
__main__block โ Builds a four-row table in memory and asserts the exact result. If the filtering logic ever breaks, this check fails loudly.
16. Dry Run
Let's trace WHERE city = 'Delhi' AND age > 20 against the table, exactly as the engine would.
FROM usersโ engine loads all four rows.WHEREevaluates each row:- Ana โ city is Delhi โ , age 25 > 20 โ โ survives
- Ben โ city is Mumbai โ โ short-circuits, dropped
- Cara โ city is Delhi โ , age 22 > 20 โ โ survives
- Dev โ city is Pune โ โ dropped
SELECT name, ageโ from survivors Ana and Cara, keep onlynameandage.
Final result: [("Ana", 25), ("Cara", 22)] โ which matches our assertion.
17. Complexity Analysis
Time complexity:
- Without an index:
O(n)โ the engine checks each ofnrows once against theWHEREcondition. This is optimal in the worst case, because any row could match, so every row must be examined. - With an index on the filtered column: closer to
O(log n + k), wherekis the number of matches. The index lets the engine skip straight to relevant rows instead of scanning all of them โ this is why filtering in SQL crushes the application-loop approach.
Space complexity: O(k) โ you only hold the k matching rows in the result, not the whole table. Contrast this with the brute-force O(n), which drags everything into memory.
The correctness of these bounds comes from the execution order: WHERE reduces the working set before SELECT and before the data ever leaves the database.
18. Alternative Solutions
A common variation is filtering with IN instead of chained ORs:
-- Instead of: WHERE city = 'Delhi' OR city = 'Mumbai'
SELECT name, age
FROM users
WHERE city IN ('Delhi', 'Mumbai');
IN is cleaner and easier to extend to many values. Functionally it's equivalent to a series of OR comparisons, and most engines optimize it identically. For ranges, BETWEEN reads better than two comparisons:
WHERE age BETWEEN 20 AND 30 -- same as age >= 20 AND age <= 30
Compared to the application-loop brute force, all of these are strictly better because they filter inside the database. Prefer whichever reads most clearly for your condition.
19. Edge Cases
- Empty table: No rows to scan, so
WHEREreturns nothing โ you get an empty result, not an error. - No matching rows: A valid query that returns zero rows. Empty is a legitimate answer, not a failure.
- Duplicates: SQL does not remove duplicate rows unless you ask with
DISTINCT. If two users share a name and city, both come back. NULLvalues:WHERE age > 20silently skips rows whereageisNULL, because comparisons withNULLare neither true nor false. UseWHERE age IS NULLto catch them.- Minimum / maximum values: Boundary conditions matter.
age > 20excludes exactly-20;age >= 20includes it. Off-by-one at the boundary is the classic bug.
20. Common Mistakes
- Quoting a number. Writing
WHERE age = '25'can trigger surprising type coercion and slow, index-defeating comparisons. Numbers stay bare:WHERE age = 25. - Forgetting quotes around text.
WHERE city = Delhimakes SQL thinkDelhiis a column name โ and it throws an error. (This one costs everybody twenty confused minutes at least once.) Text needs single quotes:WHERE city = 'Delhi'. - Reaching for
SELECT *by default. It's fine while poking around, but in real code it drags back columns nobody asked for, slows the query, and makes intent unreadable six months later. Name your columns. - Filtering in application code instead of
WHERE. Pulling a million rows to keep three wastes everything. Let the database filter close to the data. - Using
=withNULL.WHERE age = NULLnever matches anything. You must writeWHERE age IS NULL. - Confusing
AND/ORprecedence.WHERE a AND b OR cdoesn't mean what beginners expect. Use parentheses to make intent explicit.
21. Interview Questions
- What's the actual execution order of
SELECT,FROM, andWHERE? (Answer: FROM โ WHERE โ SELECT.) - Why is
SELECT *discouraged in production code? - How does
WHEREbehave withNULLvalues, and how do you filter for them? - What's the difference between filtering in the database versus filtering in the application, and why does it matter at scale?
- When would you use
INversus multipleORconditions? - Why do text literals need quotes but numbers don't?
22. Similar Problems
- LeetCode 595 โ Big Countries: Pure
SELECT+WHEREfiltering with anORcondition โ the direct sequel to this lesson. - LeetCode 584 โ Find Customer Referee: Practices
WHEREwith aNULL-aware condition, reinforcing theIS NULLedge case. - LeetCode 183 โ Customers Who Never Order: Filtering that leads naturally into
NOT INand joins. - LeetCode 1757 โ Recyclable and Low Fat Products: Combining two conditions with
AND, exactly like our Delhi-and-over-20 query.
Each one reinforces the same muscle: pick the rows, pick the columns, trust the execution order.
23. Key Takeaways
SELECTchooses columns,FROMchooses the table,WHEREchooses the rows.- The engine runs
FROMโWHEREโSELECT, even though you writeSELECTfirst. - Quote text, leave numbers bare.
- Filter where the data lives. Never drag a million rows out to keep three.
- Name your columns instead of defaulting to
SELECT *.
Read any query out loud. If it sounds like an English sentence, you're writing SQL the right way.
24. Watch the Video
Seeing the bouncer filter rows one at a time makes this click far faster than reading about it. Watch the full walkthrough here โ {LINK} โ where we run WHERE row-by-row through the users table and reveal the execution order live.
25. About the Series
This is part of Fun with Learning Technology, a series that turns intimidating engineering topics into calm, intuitive lessons. We build every concept from the ground up โ plain language first, real intuition second, code last โ so you leave understanding why things work, not just memorizing how. From SQL fundamentals to algorithms and data structures, each episode is a small, confident step forward.
26. Call To Action
If this made SQL click for you, here's how to help the series grow:
- ๐ Like the video on YouTube โ it genuinely helps more learners find it.
- ๐ Subscribe on YouTube so you don't miss the next lesson.
- ๐ฉ Subscribe on Substack for the written deep-dives like this one.
- ๐ฌ Comment with the SQL topic you want covered next.
- ๐ Share this with someone who's just starting their database journey.
SOCIAL MEDIA
LinkedIn Post
Most people think SQL is hard. It isn't. Almost every data question on Earth runs on just three words: SELECT, FROM, and WHERE.
Here's the one idea that makes it all click โ and it's the thing most beginners never get told:
You write SELECT first, but the database doesn't run it first.
The real execution order is: โ FROM grabs the table โ WHERE throws out the rows that fail its test โ SELECT keeps only the columns you asked for
Rows in, rows filtered, columns chosen. That's the whole shape.
Think of WHERE as a bouncer checking every row one at a time, asking a single yes-or-no question. Only the rows that pass get through. Once you see it that way, filtering a million-row table down to three stops feeling like magic and starts feeling like logic.
Two habits worth building early:
Quote your text, leave your numbers bare. Writing WHERE city = Delhi (no quotes) makes SQL think Delhi is a column name โ and it fails.
Filter where the data lives. Pulling a million rows into your app to keep three wastes memory, bandwidth, and time. Let WHERE do the heavy lifting next to the data.
And one honest opinion: SELECT * is overrated. Fine for exploring, painful in production. Naming your columns is a little more typing that saves real debugging pain six months later.
If you're moving from "what is a table?" to writing confident, filtered queries, this is the lesson that flips the switch.
What's the SQL habit you wish someone had taught you on day one?
#SQL #Database #SoftwareEngineering #DataAnalysis #LearnToCode
Twitter/X Thread
1/ One line of SQL can pull 3 rows out of a million. Those three words โ SELECT, FROM, WHERE โ run almost every data question on Earth. Here's how they actually work ๐งต
2/ First, the furniture. A table is just a spreadsheet. Every row = one thing (one user). Every column = one detail (their city). A "relational database" is just a bunch of these tables side by side. That's it.
3/ SELECT = which columns you want. Like telling a waiter the two dishes you want, not the whole menu. SELECT name, age โ the city column simply won't show up.
4/ FROM = which table to pull from. If SELECT orders the dishes, FROM names the restaurant. You almost never write one without the other.
5/ WHERE = the bouncer at the door. It checks every row and asks one yes-or-no question. Only the rows that answer YES get through.
6/ WHERE city = 'Delhi', row by row: Ana โ yes โ Ben โ no โ Cara โ yes โ Dev โ no โ That's genuinely all a filter does. One row at a time.
7/ Here's the trick that makes it all click: You WRITE SELECT first. But the database RUNS it last. Order: FROM โ WHERE โ SELECT. Rows in, rows filtered, columns chosen.
8/ Beginner trap #1: quotes. Text goes in single quotes. Numbers don't. WHERE city = Delhi โ SQL thinks Delhi is a column name โ error. WHERE city = 'Delhi' โ works.
9/ Beginner trap #2: SELECT *. Fine while exploring. Painful in production โ it drags back columns nobody asked for and gets unreadable in 6 months. Name your columns. Tiny bit more typing, real pain saved.
10/ And never do this: pull a million rows into your app, then filter with a loop. You just shipped a million rows to keep three. Filter where the data lives. Let WHERE do the heavy lifting. That's the whole toolkit. ๐ฏ
Facebook Post
Ever looked at a giant table of data and thought "I only need a few of these rows โ how do I just grab those?"
That's exactly what SQL is for, and you only need three words to do it: SELECT (which columns), FROM (which table), and WHERE (which rows).
The coolest part? You write SELECT first, but the database actually runs it LAST. It grabs the table, filters the rows, and only then picks your columns. Once that clicks, SQL suddenly feels like plain English: "Give me name and age, from users, where the city is Delhi."
I broke the whole thing down step by step โ including the two tiny mistakes that trip up almost every beginner. If you're just starting with databases, this one's for you. ๐
Reddit Summary
The mental model that finally made SQL's SELECT/FROM/WHERE click for me
Sharing this because it's the thing I wish someone had said on day one.
You write SELECT first, but the database doesn't execute it first. The real order is:
FROMโ load the tableWHEREโ drop every row that fails the conditionSELECTโ keep only the columns you named
So the flow is: rows in โ rows filtered โ columns chosen. Once you internalize that order, confusing queries untangle themselves.
A couple of things worth knowing early:
- Text literals go in single quotes, numbers don't.
WHERE city = Delhi(no quotes) makes SQL treatDelhias a column name and errors out.WHERE city = 'Delhi'works. - Filter in the database, not in your app. Pulling a million rows into your program to keep three wastes memory and bandwidth โ the DB is built to filter close to the data, often with an index, so let
WHEREdo it. SELECT *is fine for exploring but a bad default in real code: it returns columns nobody needs and hurts readability later.
Nothing revolutionary, just the fundamentals explained in the order that actually makes them stick. Curious what mental model helped the rest of you when SQL first clicked.
GITHUB README
# SQL Basics: SELECT, FROM, and WHERE
Pull exactly the rows and columns you need out of a table โ even one a million rows tall โ in a single line of SQL.
## Problem
Given a table of records, return only the specific **columns** and only the
specific **rows** that answer your question. Three clauses do the work:
- `SELECT` โ which columns come back
- `FROM` โ which table to read from
- `WHERE` โ which rows survive the filter
## Intuition
The key insight most beginners miss: **you write `SELECT` first, but the
database runs it last.** The real execution order is:
FROM โ WHERE โ SELECT (load) โ (filter rows) โ (pick columns)
`WHERE` acts like a bouncer, checking each row against a yes/no condition.
Only rows that pass get through. Then `SELECT` keeps only the columns you named.
## Approach
Filter **inside the database**, not in application code. The engine is built to
filter close to the data โ often using an index โ so a million-row table is
reduced to a handful of matches before anything leaves the database.
Rule of thumb: **text in single quotes, numbers bare.**
## Example
Table `users`:
| name | city | age |
|------|-------|-----|
| Ana | Delhi | 25 |
| Ben | Mumbai| 30 |
| Cara | Delhi | 22 |
| Dev | Pune | 40 |
```sql
SELECT name, age
FROM users
WHERE city = 'Delhi' AND age > 20;
Result:
| name | age |
|---|---|
| Ana | 25 |
| Cara | 22 |
Python Solution
import sqlite3
def find_users(db_path: str, city: str, min_age: int) -> list[tuple[str, int]]:
"""Return (name, age) for users in a city above a minimum age."""
query = """
SELECT name, age
FROM users
WHERE city = ? AND age > ?
"""
with sqlite3.connect(db_path) as conn:
return conn.execute(query, (city, min_age)).fetchall()
Use ? placeholders and pass parameters separately to stay safe from SQL injection.
Complexity
| Scenario | Time | Space |
|---|---|---|
| No index on filter | O(n) | O(k) |
| Indexed filter col | ~O(log n + k) | O(k) |
n = rows in the table, k = matching rows. Filtering in the database keeps
space at O(k) instead of the O(n) you'd pay dragging every row into your app.
Common Mistakes
- Quoting numbers (
age = '25') โ slow, index-defeating comparisons - Forgetting quotes on text (
city = Delhi) โ SQL treatsDelhias a column โ error - Defaulting to
SELECT *โ returns unneeded columns, hurts readability and speed - Filtering in app code instead of
WHEREโ wastes memory and bandwidth = NULLinstead ofIS NULLโ never matches
Video
๐บ Watch the full walkthrough: {LINK}
Article
๐ Read the complete written lesson with diagrams, dry runs, and edge cases in the Fun with Learning Technology series. ```
The solution
-- wrong
WHERE age = '30'
WHERE city = Delhi
-- right
WHERE age = 30
WHERE city = 'Delhi'Ready to try it yourself? Solve Sql problems with instant feedback in the practice sandbox.
Practice now โ


