SQL Tutorial › Querying Data › SELECT DISTINCT

SQL SELECT DISTINCT

BeginnerLesson 8 of 698 min read7 queries run on MySQL 8.4

A plain SELECT returns one result row for every table row, so the same value often appears many times. SELECT DISTINCT removes the duplicates and returns each unique value, or each unique combination of values, only once.

Advertisement
In this lesson
  • List the unique values of a column
  • Get distinct combinations of several columns
  • Count unique values with COUNT(DISTINCT ...)
  • How DISTINCT handles NULL

Sample data

employees · 12 rows (some columns)
emp_idfirst_namedept_idjob_titlecity
100MeeraNULLCEOMumbai
101Asha1Engineering ManagerBengaluru
102Rahul1Senior DeveloperBengaluru
103Priya1QA EngineerPune
104Karan1DeveloperBengaluru
105Vikram2Sales ManagerMumbai
106Neha2Sales ExecutiveMumbai
107Arjun2Sales ExecutiveKolkata
108Kavya3Marketing LeadPune
109Rohan3Content WriterPune
110Sneha4HR ManagerDelhi
111Amit1InternBengaluru

Duplicates without DISTINCT

Which cities do our employees work in?

SQL
SELECT cityFROM employeesORDER BY city;
ResultMySQL 8.4
city
Bengaluru
Bengaluru
Bengaluru
Bengaluru
Delhi
Kolkata
Mumbai
Mumbai
Mumbai
Pune
Pune
Pune
12 rows in set

The result has 12 rows because there are 12 employees: Bengaluru and Pune appear several times.

SELECT DISTINCT on one column

SQL
SELECT DISTINCT cityFROM employeesORDER BY city;
ResultMySQL 8.4
city
Bengaluru
Delhi
Kolkata
Mumbai
Pune
5 rows in set
How this query works, step by step
  1. FROM employees reads all 12 rows.
  2. SELECT city keeps only the city column.
  3. DISTINCT compares the rows of the result and keeps one copy of each value: 12 rows shrink to 5 cities.
  4. ORDER BY city sorts them alphabetically.

DISTINCT on several columns

With more than one column, DISTINCT removes rows where all the listed columns are the same. It works on the combination, not on each column separately:

SQL
SELECT DISTINCT dept_id, cityFROM employeesORDER BY dept_id, city;
ResultMySQL 8.4
dept_idcity
NULLMumbai
1Bengaluru
1Pune
2Kolkata
2Mumbai
3Pune
4Delhi
7 rows in set
How this query works, step by step
  1. MySQL builds (dept_id, city) pairs for all 12 employees.
  2. Pairs that occur more than once, such as (1, Bengaluru) for four engineers, are kept once.
  3. Department 1 still appears twice, because it has two different cities: Bengaluru and Pune.
  4. The CEO’s pair (NULL, Mumbai) is a combination of its own.

DISTINCT and NULL

DISTINCT treats all NULLs as equal, so they collapse into one NULL row:

SQL
SELECT DISTINCT commissionFROM employeesORDER BY commission;
ResultMySQL 8.4
commission
NULL
4500
6000
12000
4 rows in set
How this query works, step by step
  1. Nine employees have no commission (NULL) and three sales staff have one.
  2. The nine NULLs become a single NULL row, and the three amounts are all different.
  3. In ascending order MySQL puts NULL first.

COUNT(DISTINCT column)

To count how many different values a column has, put DISTINCT inside COUNT:

SQL
SELECT COUNT(*)             AS employees,       COUNT(city)          AS rows_with_city,       COUNT(DISTINCT city) AS different_cities,       COUNT(DISTINCT dept_id) AS departments_usedFROM employees;
ResultMySQL 8.4
employeesrows_with_citydifferent_citiesdepartments_used
121254
1 row in set
How this query works, step by step
  1. COUNT(*) counts every row: 12.
  2. COUNT(city) counts rows where city is not NULL: also 12.
  3. COUNT(DISTINCT city) counts unique cities: 5.
  4. COUNT(DISTINCT dept_id) ignores the CEO’s NULL and counts 4 departments.

Which customers have placed at least one order? DISTINCT turns “one row per order” into “one row per customer”:

SQL
SELECT DISTINCT customer_idFROM ordersORDER BY customer_id;
ResultMySQL 8.4
customer_id
1
2
3
4
5
5 rows in set

DISTINCT vs GROUP BY

SELECT DISTINCT city FROM employees and SELECT city FROM employees GROUP BY city return the same rows. Use DISTINCT when you only want unique rows; use GROUP BY when you also want a count, sum or other aggregate per group:

SQL
SELECT city, COUNT(*) AS staffFROM employeesGROUP BY cityORDER BY staff DESC, city;
ResultMySQL 8.4
citystaff
Bengaluru4
Mumbai3
Pune3
Delhi1
Kolkata1
5 rows in set
Watch out

DISTINCT is not a fix for a wrong join. If a query returns unexpected duplicates, find out why (often a missing join condition) instead of hiding them with DISTINCT. Removing duplicates also costs time on large results.

Exercise: Unique job titles

List each distinct job_title in the employees table, sorted alphabetically.

Expected resultMySQL 8.4
job_title
CEO
Content Writer
Developer
Engineering Manager
HR Manager
Intern
Marketing Lead
QA Engineer
Sales Executive
Sales Manager
Senior Developer
11 rows in set
Hint 1

Put DISTINCT straight after SELECT.

Exercise: How many product categories?

Count how many different category values the products table has. Name the column categories.

Expected resultMySQL 8.4
categories
3
1 row in set
Hint 1

Use COUNT(DISTINCT category).

Quick quiz

1. SELECT DISTINCT dept_id, city removes a row when…

2. A column has the values 5, NULL, 5, NULL. What does SELECT DISTINCT return?

3. What does COUNT(DISTINCT city) count?

SELECT DISTINCT FAQ

What does SELECT DISTINCT do in SQL?

It removes duplicate rows from the result, so each unique value or combination of values appears once.

Does DISTINCT apply to all columns?

Yes. DISTINCT always applies to the whole row of selected columns. There is no way to make it apply to only the first column; use GROUP BY or a window function for that.

Is DISTINCT faster than GROUP BY?

For simply removing duplicates, MySQL usually runs both the same way. Choose the one that states your intent: DISTINCT for unique rows, GROUP BY when you aggregate.

How do I count distinct values in SQL?

Use COUNT(DISTINCT column). It counts the different non-NULL values of the column.