Here is a way to do what you described - it is sort of a bruteforce approch, but the logic should be easy to follow. And, by the way, your explanation makes perfect sense :) Instead of the delete in each query, uncomment the select line and run that to see the count of duplicates.-- Starting with file #20;;WITH cte AS( surname + LEFT(addressline1,6) AS DuplicateCriterion, SELECT ROW_NUMBER() OVER ( PARTITION BY surname + LEFT(addressline1,6) ORDER BY (SELECT NULL) -- or some other condition ) AS RN FROM YourTable WHERE keycode = 20;)--SELECT DuplicateCriterion,COUNT(*) AS Records FROM cte--HAVING COUNT(*) > 1DELETE FROM cte WHERE RN > 1;-- For File 20 and File 19;;WITH cte AS( surname + LEFT(addressline1,6) AS DuplicateCriterion, SELECT ROW_NUMBER() OVER ( PARTITION BY surname + LEFT(addressline1,6) ORDER BY (SELECT NULL) -- or some other condition ) AS RN FROM YourTable WHERE keycode IN (19,20))--SELECT DuplicateCriterion,COUNT(*) AS Records FROM cte--HAVING COUNT(*) > 1DELETE FROM cte WHERE RN > 1;-- repeat for the remaining by changing the where clause to-- WHERE keycode IN (18,19,20)-- WHERE keycode IN (17,18,19,20)-- etc.