Senger CodeLab 🚀

T-SQL Deleting all duplicate rows but keeping one duplicate

September 29, 2026

📂 Categories: Sql
T-SQL Deleting all duplicate rows but keeping one duplicate

Dealing with duplicate rows in a SQL Server database can be a major headache, especially when they clutter your data and skew your analysis. Imagine trying to generate a report only to find inflated numbers due to redundant entries. Fortunately, T-SQL offers powerful tools to tackle this issue effectively. This post will delve into various techniques for deleting duplicate rows in a SQL Server table while retaining one unique instance, ensuring data integrity and accuracy.

Understanding Data Duplication

Before diving into solutions, it’s crucial to understand why duplicates occur. Common causes include data entry errors, data integration issues from multiple sources, or even application logic flaws. Identifying the root cause can help prevent future duplicates. Data duplication can lead to inaccurate reporting, wasted storage space, and performance degradation. Recognizing the source of duplication is the first step towards a cleaner, more efficient database.

According to a study by Data Quality Solutions, on average, organizations believe 15-20% of their data is duplicated. This highlights the prevalence and potential impact of this issue across various industries. Clearly, efficient duplicate removal is a critical skill for any SQL Server developer.

Using the ROW_NUMBER() Function

One of the most effective ways to delete duplicates is using the ROW_NUMBER() function. This function assigns a unique sequential number to each row within a partition based on specified criteria. We can then delete rows with a row number greater than 1, effectively removing duplicates while keeping the first occurrence of each unique record.

Here’s how you can implement this technique:

WITH RankedRows AS ( SELECT column1, column2, ..., ROW_NUMBER() OVER (PARTITION BY column1, column2, ... ORDER BY some_column) as rn FROM your_table ) DELETE FROM RankedRows WHERE rn > 1; 

This code snippet partitions the data based on the specified columns and orders it by another column (e.g., a primary key or timestamp). The DELETE statement then removes all rows with a row number greater than 1, leaving only the first unique entry.

Choosing the Right Partitioning Columns

The columns you choose for partitioning determine which rows are considered duplicates. Select the columns that uniquely define a record. For instance, if you have a table of customers, you might partition by email address or a unique customer ID.

Utilizing the Common Table Expression (CTE)

The Common Table Expression (CTE) simplifies the process by creating a temporary named result set. This improves readability and allows you to organize complex queries more effectively. The CTE approach is particularly useful when dealing with large datasets or complex duplicate identification logic.

WITH DuplicateRows AS ( SELECT column1, column2, ..., COUNT() AS DuplicateCount FROM your_table GROUP BY column1, column2, ... HAVING COUNT() > 1 ) DELETE FROM your_table WHERE EXISTS ( SELECT 1 FROM DuplicateRows WHERE your_table.column1 = DuplicateRows.column1 AND your_table.column2 = DuplicateRows.column2 ... -- Add other matching conditions ); 

This CTE identifies rows that appear more than once and then uses an EXISTS clause in the DELETE statement to remove them. This approach offers a concise and manageable way to remove duplicate records.

The DISTINCT Keyword and DELETE

While DISTINCT is primarily used for selecting unique rows, it can also be leveraged for deleting duplicates in certain scenarios. Be cautious with this method, as it may not preserve the original row if you have an identity column or timestamp.

Preventing Future Duplicates

Once you’ve cleaned up your data, implementing preventative measures is crucial. This could involve enforcing unique constraints on your database tables, implementing data validation rules at the application level, or even improving data entry processes to minimize human error. Preventing duplicates at the source is often more efficient than repeatedly cleaning them up later.

  • Implement unique constraints or indexes.
  • Validate data before insertion.

For more in-depth information on data quality management, explore resources like Talend’s data quality guide and IBM’s data quality solutions.

Featured Snippet: Removing duplicate rows in SQL Server can be achieved using various techniques including the ROW_NUMBER() function, Common Table Expressions (CTEs), and in some cases, the DISTINCT keyword. Choosing the right method depends on the specific needs of your data and the structure of your tables. Always back up your data before performing delete operations.

  1. Identify the columns that define uniqueness.
  2. Choose the appropriate T-SQL method.
  3. Test your query on a sample dataset first.

Learn more about SQL Server best practices on our blog: SQL Server Optimization Techniques.

Further reading on T-SQL:Microsoft T-SQL Documentation.

Best Practices for Data Cleaning

Regularly cleaning your data is vital for maintaining data integrity. Schedule routine checks and implement automated scripts to address potential duplicates. Early detection and removal minimize the impact on downstream processes and reporting. Implementing these best practices can save time and resources in the long run.

  • Schedule regular data cleaning tasks.
  • Automate data cleaning processes.

Another excellent resource is Brent Ozar’s website, which offers valuable insights and tips on SQL Server performance tuning and data management.

[Infographic Placeholder]

Frequently Asked Questions

Q: What are the potential consequences of duplicate data?

A: Duplicate data can lead to inaccurate reporting, inflated metrics, and poor decision-making. It can also waste storage space and impact database performance.

Q: How can I prevent duplicates from being inserted in the first place?

A: Implementing unique constraints, validating data before entry, and standardizing data entry procedures can help prevent duplicates from being inserted.

Eliminating duplicate data is a vital aspect of maintaining a healthy and efficient SQL Server database. By utilizing the techniques discussed in this post, you can effectively remove duplicate rows while ensuring that you retain one copy of each unique record. Implementing preventative measures and incorporating regular data cleaning practices can further enhance your data integrity and streamline your data management processes. Start cleaning your data today and experience the benefits of a more accurate and reliable database. Explore the resources mentioned and delve deeper into the world of T-SQL for even more advanced data manipulation techniques.

Question & Answer :

I have a table with a very large amount of rows. Duplicates are not allowed but due to a problem with how the rows were created I know there are some duplicates in this table. I need to eliminate the extra rows from the perspective of the key columns. Some other columns may have *slightly* different data but I do not care about that. I still need to keep one of these rows however. SELECT DISTINCT won't work because it operates on all columns and I need to suppress duplicates based on the key columns.

How can I delete the extra rows but still keep one efficiently?

You didn’t say what version you were using, but in SQL 2005 and above, you can use a common table expression with the OVER Clause. It goes a little something like this:

WITH cte AS ( SELECT[foo], [bar], row_number() OVER(PARTITION BY foo, bar ORDER BY baz) AS [rn] FROM TABLE ) DELETE cte WHERE [rn] > 1 

Play around with it and see what you get.

(Edit: In an attempt to be helpful, someone edited the ORDER BY clause within the CTE. To be clear, you can order by anything you want here, it needn’t be one of the columns returned by the cte. In fact, a common use-case here is that “foo, bar” are the group identifier and “baz” is some sort of time stamp. In order to keep the latest, you’d do ORDER BY baz desc)