Beginner: asking questions · SELECT: filtering and sorting · topic 10 of 62 · 30 min
DISTINCT and how a query runs
Explanation
DISTINCT: each answer once
Which cities do our customers live in? SELECT city FROM customers gives Pune twice, because two customers live there. DISTINCT keeps one copy of each repeated row.
SELECT DISTINCT city FROM customers;
-- Pune
-- Delhi
-- Chennai
-- Mumbai
-- HyderabadDISTINCT on many columns
DISTINCT looks at the whole row of selected columns, not at the first column only. SELECT DISTINCT city, course gives each different pair once. Pune appears three times in the result, because Pune has BCA, BCom and BSc students.
SELECT DISTINCT city, course FROM students ORDER BY city, course;
-- Chennai | BCA
-- Delhi | BCom
-- Delhi | BSc
-- Hyderabad | BCA
-- Mumbai | BSc
-- Pune | BCA
-- Pune | BCom
-- Pune | BScDISTINCT treats NULLs as equal to each other, so all NULLs collapse into one row. SELECT DISTINCT dept_id FROM employees returns one NULL (for Deepak) plus 1, 2, 3 and 4.
A preview: counting distinct values
SELECT COUNT(DISTINCT city) FROM students; -- 5Written order versus run order
You must write the clauses of a query in a fixed order. But the database works them out in a different order, called the logical order. Knowing it explains many errors.
| Step | Clause | What happens |
|---|---|---|
| 1 | FROM | Pick the table (later, join tables) |
| 2 | WHERE | Keep only the rows that pass the condition |
| 3 | GROUP BY / HAVING | Group rows and filter groups (module 4) |
| 4 | SELECT | Work out the columns and expressions; aliases are born here |
| 5 | DISTINCT | Remove repeated rows |
| 6 | ORDER BY | Sort; aliases from step 4 can be used |
| 7 | LIMIT / OFFSET | Keep only some of the sorted rows |
Why an alias fails in WHERE
An alias is created in step 4, SELECT. WHERE runs in step 2, before the alias exists. So the standard way is to repeat the expression in WHERE, and to use the alias in ORDER BY, which runs after SELECT.
SELECT name, salary * 12 AS annual
FROM employees
WHERE salary * 12 >= 1200000 -- repeat the expression here
ORDER BY annual DESC; -- the alias works here
-- Meera Iyer | 3000000
-- Rahul Sharma | 1440000
-- Pooja Gupta | 1320000
-- Farhan Ali | 1260000Reading a query aloud
Reading in the logical order helps you check a query. For the query above: "From employees, keep those whose salary times 12 is at least 12 lakh, show their name and annual salary, and sort by annual salary, highest first." If the sentence sounds wrong, the query probably is.
Common mistakes
- Using DISTINCT to hide duplicate rows caused by a wrong query (often a bad join, module 5). Find the cause instead.
- Thinking DISTINCT applies to the first column only. It applies to the whole selected row.
- Using a SELECT alias in WHERE. Repeat the expression, or use a subquery (module 6).
- Writing clauses in the wrong order, like ORDER BY before WHERE. The written order is SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
DISTINCT and how a query runs · 1/7
Two ideas in this lesson: removing repeats with DISTINCT, and the order in which a query really runs.
Prefer a video by a teacher? Find free videos on “sql distinct logical order of query execution alias where order by” on YouTube ↗
In real life: Filling a drop-down menu
A food delivery app shows a "Cuisine" filter with North Indian, South Indian, Chinese and so on. The list is not typed by hand; it comes from SELECT DISTINCT cuisine FROM restaurants ORDER BY cuisine, so a new cuisine appears in the menu as soon as the first restaurant of that kind joins.
SELECT DISTINCT category FROM products ORDER BY category;
-- Electronics
-- Fashion
-- Grocery
-- KitchenPractice (0/4 done)
Which cities do the SHOP customers live in? Return each city once (one column: city).
Return every product category once (one column: category).
Which categories have at least one product priced above 1000? Return each category once, sorted A to Z (one column: category).
salary in COMPANY is per month. Return name and salary * 12 named annual, only for employees whose annual pay is at least 1200000, sorted by annual from highest to lowest. Repeat the expression in WHERE and use the alias in ORDER BY.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- IN, BETWEEN, LIKE and NULLSELECT: filtering and sorting · same module
- ORDER BY, LIMIT and DISTINCTBackend Development · Databases and SQL basics
- GROUP BYAggregation: GROUP BY and HAVING
- HAVING versus WHEREAggregation: GROUP BY and HAVING
- SELECT and WHERE: finding rowsBackend Development · Databases and SQL basics
- INSERTChanging data, transactions and ACID
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
In which logical order are these clauses worked out?
Answer: FROM, WHERE, SELECT, ORDER BY
FROM picks the table, WHERE filters, SELECT builds columns, ORDER BY sorts.
Why can ORDER BY use a SELECT alias, while standard SQL does not allow it in WHERE?
Answer: ORDER BY runs after SELECT, WHERE runs before it
The alias exists only from the SELECT step onward.
SELECT DISTINCT city, course FROM students: what is removed?
Answer: Rows where both city and course repeat together
DISTINCT compares the whole selected row.
dept_id has the values 1, 1, 2, NULL, NULL. How many rows does SELECT DISTINCT dept_id return?
Answer: 3
DISTINCT treats NULLs as equal, so the result is 1, 2 and one NULL.
Your query returns duplicate rows. When is adding DISTINCT the wrong fix?
Answer: When the duplicates come from a mistake in the query, such as a wrong join
DISTINCT hides the symptom; fix the query that makes the extra rows.
What does SELECT DISTINCT city FROM customers return?Related
Answer: Each city only once
DISTINCT removes repeated rows, so each city appears once.
students has 8 rows in 5 different cities. How many rows does SELECT city, COUNT(*) FROM students GROUP BY city return?Related
SELECT city, COUNT(*) AS n FROM students GROUP BY city HAVING n > 1 works in SQLite. What happens in PostgreSQL?Related
Answer: It fails, because a SELECT alias is not visible in HAVING
HAVING runs before SELECT in standard SQL. Write HAVING COUNT(*) > 1.
From HAVING versus WHERE
What does SELECT name FROM students WHERE marks > 80 return?Related
Answer: Names of students with marks above 80
SELECT name picks one column; WHERE marks > 80 keeps only the rows with more than 80.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “SELECT: filtering and sorting”. The module exam comes next.
- Module 2 exam: SELECT, filtering and sorting · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Functions, CASE and NULL. 62 topics left in the course before the final exam.