SQL DISTINCT
Remove repeated projected rows without changing stored data, and project only the columns whose duplicates should collapse.
DISTINCT collapses duplicate result rows
10 stored rowsCategories repeat because many courses share Data, Web, or Backend.
unique valuesRepeated category values collapse in the result, not in the table.
Backend, Data, WebThe short list still needs an explicit display order.
SELECT DISTINCT returns unique projected values
The courses table has ten rows but only three category values: Backend, Data, and Web. SELECT DISTINCT category returns each category once. It does not delete duplicate source rows, and it does not mean that categories are unique in the table. The final ORDER BY category gives the short list a predictable display order.
List unique category values
Turn repeated course categories into a three-row result.
Edit the query, predict the rows it will return, then run it.
DISTINCT considers the whole selected row
SELECT DISTINCT category, status returns unique pairs, not one row per category. Data and Web each have both published and draft courses, while Backend has only published courses. The result therefore has five rows. When the query projects multiple columns, two result rows collapse only when every selected value matches. Adding course_id would make every row unique and defeat this use of DISTINCT.
Compare category-status pairs
See how one more projected column changes what counts as a duplicate.
Edit the query, predict the rows it will return, then run it.
DISTINCT does not repair a wrong join
Use DISTINCT when the question truly asks for unique projected values: the set of categories, the set of published statuses, or another list whose duplicates are not useful. If an unexpected join duplicates whole entities, inspect the join and its relationship keys before hiding the extra rows with DISTINCT. Collapsing those rows can hide a grain mistake and make counts look smaller than the duplicated work actually was.
Common DISTINCT mistakes
Deduplication at the wrong grain
The unique ID keeps each row distinct. Project only the values whose duplicates should collapse.
Hidden duplication
If whole courses repeat, the join or grouping is wrong. Distinct values will not restore the intended grain.
An unordered unique list
Uniqueness and display order are separate contracts. Sort the short list when a reviewer needs a sequence.
Result-only collapse
DISTINCT does not add a unique constraint and does not delete stored rows.
Independent lab: list published categories
List each published category once in alphabetical order. The starter query should return Backend, Data, and Web. Remove DISTINCT and count how many published rows share those three labels, then restore it. Adding status to the select list should not grow this published-only result, because every remaining row is published.
List distinct published categories
Collapse published category values and keep the short list alphabetical.
Edit the query, predict the rows it will return, then run it.
Lesson review
DISTINCT collapses equal projected rows, so its meaning depends on the selected columns. Unique category values are not the same as unique category-status pairs. The clause does not change stored data and does not repair a query that duplicated entities for the wrong reason. Order the unique list when the display sequence should be a contract.
- I can distinguish unique category values from unique category-status pairs.
- I know DISTINCT applies to the whole projected row.
- I will not use DISTINCT to hide a duplicated join.
- I can order a unique list so the display is reviewable.