Loading…
Loading…
SQL tutorial · Beginner
⏱️ 6 mins read
DISTINCT removes duplicate rows from a result set. When applied to multiple columns, it returns unique COMBINATIONS of those columns — not unique values per column independently. COUNT(DISTINCT col) counts unique non-null values in a column.
SELECT DISTINCT col FROM table;
SELECT DISTINCT col1, col2 FROM table;
SELECT COUNT(DISTINCT col) FROM table;-- Unique department IDs
SELECT DISTINCT department_id FROM employees;
-- Unique city + country combinations
SELECT DISTINCT city, country
FROM customers;
-- How many distinct cities do customers live in?
SELECT COUNT(DISTINCT city) AS unique_cities
FROM customers;| id | name | city | country | signup_date | |
|---|---|---|---|---|---|
| 1 | Karl | karl@example.com | Berlin | Germany | 2023-01-10 |
| 2 | Ines | ines@example.com | Berlin | Germany | 2023-02-14 |
| 3 | Omar | omar@example.com | Berlin | Austria | 2023-05-30 |
| 4 | Sofia | sofia@example.com | London | UK | 2023-08-22 |
| 5 | Maike | maike@example.com | NULL | NULL | 2023-11-05 |
employees (from Topic 1) — department_id only: 1=Ada(1), 2=Grace(1), 3=Alan(2), 4=Edsger(NULL), 5=Barbara(3)
SELECT DISTINCT city, country returns unique PAIRS: ('Berlin','Germany') appears once, but ('Berlin','Germany') and ('Berlin','Austria') are two different rows and both survive. The unit of uniqueness is the entire selected row — never each column separately.
-- ShopCo customers (from the Data in play panel):
-- id | name | city | country
-- 1 | Karl | Berlin | Germany
-- 2 | Ines | Berlin | Germany
-- 3 | Omar | Berlin | Austria
-- 4 | Sofia | London | UK
-- 5 | Maike | NULL | NULL
SELECT DISTINCT city, country FROM customers
ORDER BY country, city;
-- (Berlin, Austria), (Berlin, Germany), (London, UK), (NULL, NULL) — 4 rows:
-- the Berlin/Germany pair collapsed to one; both NULLs count as one rowDuplicates in a result come from two places: the data legitimately contains them, or your query manufactured them — usually a JOIN (Topic 15) matching multiple rows per key. DISTINCT removes both kinds identically, so it can silently destroy real data while you patch a query bug.
-- Legitimate: the list of cities we operate in
SELECT DISTINCT city FROM customers;
-- Suspicious: 'every customer suddenly appears twice'
-- SELECT DISTINCT * FROM customers;
-- ^ masks a duplicate-import bug instead of surfacing itFour of our five customers have a city; two share Berlin. COUNT(*) says 5 (every row), COUNT(city) says 4 (non-NULL values), COUNT(DISTINCT city) says 2 (unique values). Three related questions, three different answers — picking the wrong one is a quiet analytics bug.
SELECT
COUNT(*) AS all_customers, -- every row, NULL or not
COUNT(city) AS customers_with_city, -- skips Maike's NULL city
COUNT(DISTINCT city) AS unique_cities -- collapses duplicates
FROM customers;
-- 5 | 4 | 2Assuming DISTINCT applies per column separately. SELECT DISTINCT a, b returns unique (a, b) pairs, not unique a values AND unique b values independently. DISTINCT also has performance overhead on large datasets — prefer GROUP BY for complex deduplication.
Interviewers sometimes ask to deduplicate with row priority (e.g., keep the most recent row). For that, use ROW_NUMBER() window function rather than DISTINCT.
1. What is the unit of uniqueness for SELECT DISTINCT city, country?
2. ShopCo has 5 customers: Karl/Ines both (Berlin, Germany), Omar (Berlin, Austria), Sofia (London), Maike (NULL, NULL). How many rows does DISTINCT city, country return?
3. On ShopCo's customers, what do COUNT(*), COUNT(city), and COUNT(DISTINCT city) return?
4. A teammate adds DISTINCT and 'the duplicates are gone'. Why be suspicious?
5. SELECT DISTINCT department_id FROM employees is equivalent to…?
6. Why can DISTINCT be slow on large result sets?
Return each distinct order status exactly once.
⚡ Solve it in the SQL playground →It can be: deduplication generally requires sorting or hashing the whole result set, which defeats indexes and blocks streaming. If duplicates only exist because of a JOIN fan-out, fixing the JOIN is both faster and more correct than DISTINCT on top.
For pure deduplication they are equivalent (most engines produce the same plan). GROUP BY exists to power aggregates (Topic 9) and HAVING (Topic 10); reserving DISTINCT for 'I want unique values' and GROUP BY for 'I want per-group numbers' keeps intent readable.