DISTINCT
Learn how to remove duplicate rows from SQL Server query results using DISTINCT, including DISTINCT across multiple columns.
Introduction
Real-world tables often contain repeated values — many employees might share the same department, or many orders might share the same status. When you only care about the unique set of values, not every repeated occurrence, the DISTINCT keyword removes duplicate rows from your query results.
- How DISTINCT removes duplicate rows.
- How DISTINCT behaves across multiple selected columns.
- How DISTINCT differs from GROUP BY.
Basic DISTINCT
DISTINCT is placed immediately after SELECT. It tells SQL Server to evaluate the full set of returned rows and eliminate any rows that are exact duplicates of another row in the result.
SELECT Department FROM Employees;
SELECT DISTINCT Department FROM Employees;Click Run to see what this code prints.
Click Run to see what this code prints.
Notice that Engineering, which appeared twice, is collapsed into a single row when DISTINCT is applied. NULL is also treated as a distinct value and appears only once even if it occurs multiple times.
DISTINCT with Multiple Columns
When DISTINCT is applied to more than one column, SQL Server considers the combination of all selected columns together. Two rows are only removed as duplicates if every selected column matches.
SELECT DISTINCT Department, SalaryFROM Employees;Click Run to see what this code prints.
Even though "Engineering" appears twice here, the rows are not merged because their Salary values differ — the two columns together form a unique combination.
DISTINCT vs GROUP BY
DISTINCT and GROUP BY can sometimes produce similar-looking results, but they serve different purposes. DISTINCT simply removes duplicate rows from the output. GROUP BY groups rows together specifically so you can apply aggregate functions like COUNT or SUM per group. If you are not aggregating anything, DISTINCT is usually the simpler and more appropriate choice.
If your goal is to count how many employees are in each department, GROUP BY with COUNT(*) is the right tool. DISTINCT alone cannot produce per-group counts.
Common Mistakes
- Assuming DISTINCT only removes duplicates in the first column when multiple columns are selected — it considers the full row combination.
- Using DISTINCT as a substitute for GROUP BY when aggregate calculations are actually needed.
- Applying DISTINCT to a primary key column expecting it to reduce rows — since primary keys are already unique, DISTINCT has no effect.
- Overusing DISTINCT to mask a join that is producing unwanted duplicate rows, instead of fixing the underlying join condition.
Best Practices
- Use DISTINCT only when you specifically need unique rows, not as a general-purpose fix for messy queries.
- If duplicates come from a join, investigate the join condition rather than papering over it with DISTINCT.
- Prefer GROUP BY when you need per-group aggregate values, not just unique combinations.
- Be aware that DISTINCT requires SQL Server to sort or hash the result set, which has a performance cost on large tables.
Frequently Asked Questions
Yes. SQL Server treats all NULLs as equal to each other for the purpose of DISTINCT, so multiple NULL rows collapse into a single NULL row in the output.
It can be, since SQL Server typically needs to sort or hash the result set to identify duplicates. On large unindexed result sets this adds overhead.
Yes — COUNT(DISTINCT ColumnName) counts the number of unique, non-NULL values in a column, which is a very common pattern for reporting.
Key Takeaways
- DISTINCT removes duplicate rows from a result set.
- With multiple columns, DISTINCT considers the full combination of values.
- DISTINCT treats NULL as a single repeatable value.
- GROUP BY is the better tool when you need aggregate values per group.
- DISTINCT has a performance cost since SQL Server must identify duplicates.
Summary
DISTINCT is a simple but powerful tool for producing unique result sets. Next, you will look more closely at aliases — a concept you have already used with AS — and see why they matter especially once you start writing joins.