Hook: DISTINCT is the SQL bouncer: it only lets through rows that look unique after your SELECT list is applied.
Question: What does DISTINCT do in SQL?
Answer: DISTINCT removes duplicate rows from the result set. It compares the columns you selected as one whole row, not each column separately. That means SELECT DISTINCT email and SELECT DISTINCT email, city can return very different results.
Interview-Ready Answer: I use DISTINCT when I want one copy of each unique result row. The important detail is that it deduplicates the final selected columns as a tuple, so SELECT DISTINCT email is not the same as SELECT DISTINCT email, id. Under the hood the database usually hashes or sorts the rows to remove duplicates, so it can be more expensive than it looks on large data.
DISTINCT really meansDetailed Explanation: SQL normally keeps duplicates unless you ask it not to. DISTINCT says, “show me only unique rows from this projection.” A projection means the columns or expressions in the SELECT list. So the database does not dedupe the original table first; it dedupes the rows after the selected columns are computed.
FROM, joins, and WHERE.SELECT list.ORDER BY is applied to that final set.Most engines use one of two physical strategies: a hash-based distinct or a sort-based distinct. A hash method stores seen rows in memory and checks each new row against that set. A sort method orders the rows first, then removes neighbors that are equal. Both are correct; the optimizer chooses based on data size, available indexes, and memory.
| Feature | DISTINCT | GROUP BY |
|---|---|---|
| Main job | Remove duplicates | Form groups |
| Aggregates | Not required | Common |
| Readability | Simple dedupe | Good for counts |
| Typical use | Unique list | Totals, counts |
When to use it: use DISTINCT for a clean unique list, like unique emails, countries, or category names. Use GROUP BY when you also need aggregates such as COUNT, SUM, or MAX. In many databases, GROUP BY without aggregates can look similar to DISTINCT, but DISTINCT is usually clearer when you only want deduplication.
id, duplicates may disappear from the dedupe logic because every row is now different.NULL values collapse together. For duplicate removal, SQL treats multiple NULLs as one distinct value in the result.ORDER BY can be tricky. Many engines require the ordered column to appear in the select list when DISTINCT is used, because the sort happens after deduplication.O(n log n) work and may write temp files too.Memory model: if the engine uses a hash table, the space is roughly proportional to the number of unique rows, not total rows. That is why DISTINCT on a column with almost every value unique can be memory-heavy. If an index already orders the needed columns, some databases can avoid extra work by reading in sorted order.
Memory Hook: Think of DISTINCT as stamping each unique outfit once. If the selected columns change even a little, it is a new outfit and gets a new stamp.
Real-World Example: Imagine a marketing export job in a checkout service that sends a daily list of customer emails to a campaign tool. The team writes SELECT DISTINCT email, customer_id because they want unique emails, but the extra customer_id makes every row unique. The campaign tool receives duplicate emails, some users get two copies of the same message, and support tickets spike.
In the logs, the job looks healthy: row count is high, no SQL error appears, and the export file is created on time. The hidden bug is semantic, not technical: the query is syntactically valid, but the deduplication key is wrong. The fix is to select only the business key you truly want unique, such as email, or to use a proper grouping/window approach if you also need the newest profile data.
The symptom pattern is classic: duplicate recipients, repeated inserts into a downstream table, and complaint emails like “I got this twice.” Interviewers love this example because it shows that DISTINCT is not a magic anti-bug button; it only dedupes exactly what you ask it to dedupe.
-- Standard SQL example: how DISTINCT removes duplicate result rows
-- The table stores repeated business data on purpose so we can see deduping clearly.
CREATE TABLE customers (
customer_id INTEGER,
email VARCHAR(100),
city VARCHAR(50),
country VARCHAR(50)
);
INSERT INTO customers (customer_id, email, city, country) VALUES
(1, 'alice@example.com', 'New York', 'USA'),
(2, 'alice@example.com', 'Boston', 'USA'),
(3, 'bob@example.com', 'Paris', 'France'),
(4, NULL, 'Paris', 'France'),
(5, NULL, 'Paris', 'France'),
(6, 'carol@example.com', 'Paris', 'France'),
(7, 'carol@example.com', 'Paris', 'France');
-- 1) One row per unique email.
-- NULL appears only once because DISTINCT collapses duplicate NULLs in the result set.
SELECT DISTINCT email
FROM customers
ORDER BY email;
-- 2) One row per unique city/country pair.
-- This is different from distinct city alone: the pair is the unit being deduped.
SELECT DISTINCT city, country
FROM customers
ORDER BY country, city;
-- 3) Failure path: including customer_id defeats the goal.
-- Every customer_id is unique, so this query does NOT dedupe by email.
SELECT DISTINCT customer_id, email
FROM customers
ORDER BY email, customer_id;
-- 4) If you only want real email values, filter NULL first.
-- DISTINCT is about uniqueness, not validation.
SELECT DISTINCT email
FROM customers
WHERE email IS NOT NULL
ORDER BY email;Follow-up & Tricky Questions:
GROUP BY instead of DISTINCT? Use GROUP BY when you need aggregates like counts or sums. Use DISTINCT when you only want unique rows and do not need calculations.DISTINCT remove duplicates before or after WHERE? After WHERE. The filter reduces the candidate rows first, then DISTINCT removes duplicates from what is left.DISTINCT treat NULL? For duplicate elimination, multiple NULL values are treated as the same distinct output value, so you usually get one NULL back.DISTINCT be used with joins? Yes, but be careful: it can hide a bad join that creates extra rows. It is better to fix the join condition than to cover the symptom with DISTINCT.DISTINCT be slow? Because the database may need to sort or hash a large row set. If many rows are unique, memory use and temp-file I/O can grow quickly.DISTINCT pick the newest row? No. It does not choose by time or priority; it only removes identical selected rows. To pick the latest row per key, you usually need a window function.DISTINCT is present, because the final row shape is defined by the select list. The safe habit is to sort by selected columns.SELECT DISTINCT * always mean one row per business entity? No. It means one row per fully identical row across all columns. If any column differs, the rows stay separate.DISTINCT the same as UNIQUE? Not exactly. UNIQUE is a constraint that enforces uniqueness in stored data, while DISTINCT is a query-time operation that filters the result set.DISTINCT change the table? No. It only changes what the query returns; it does not delete or update rows in the table.DISTINCT remove duplicates from each column separately? No. That is a common mistake. It compares the entire selected row, so SELECT DISTINCT city, country keeps unique pairs, not unique cities and unique countries independently.SELECT DISTINCT id, email dedupe duplicate emails? Usually not, because different id values make the rows different. If your dedupe key is email, select only email or group by email.Common Mistakes:
id, you may destroy the dedupe logic. Select only the columns that define uniqueness.DISTINCT to hide a bad join. Correction: fix the join cardinality first; dedupe only at the end if the business meaning truly requires it.DISTINCT does not mean “keep the latest” or “keep the biggest”; it only removes identical projected rows.NULL. Correction: if you want only real values, add WHERE col IS NOT NULL before DISTINCT.Memory Hook: “Distinct checks the outfit, not the passport.” The outfit is the selected columns; if the outfit is the same, one row stays and the rest go away.
Cheat Sheet:
DISTINCT removes duplicate result rows.NULLs collapse to one output row.GROUP BY is better when you need aggregates.Practice Tasks:
customers table.city, country pairs and compare the row counts.SELECT DISTINCT id, email and fix it so it truly dedupes by email.