3

I want to delete duplicate records without using ROW_NUMBER() function (SQL Server)

Example: Table with the following data:

name     salary
-----------------
Husain   20000.00
Husain   20000.00
Husain   20000.00
Munavvar 50000.00
Munavvar 50000.00

After deleting the duplicate records table should contains data like this:

name     salary
-----------------
Husain   20000.00
Munavvar 50000.00
Munavvar
  • 802
  • 1
  • 11
  • 33

5 Answers5

9

As the motivation for this question seems to be academic interest rather than practical use...

The table has no primary key but the undocumented pseudo column %%physloc%% can provide a substitute.

DELETE T1
FROM YourTable T1 WITH(TABLOCKX)
WHERE CAST(T1.%%physloc%% AS BIGINT)
NOT IN (SELECT MAX(CAST(%%physloc%% AS BIGINT))
        FROM YourTable 
        GROUP BY Name, Salary)

In reality you should never use the above and just use row_number as it is more efficient and documented.

(Data Explorer Demo)

Community
  • 1
  • 1
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
4

Another (academic) option, depending on what version of SQL server you're using:

;with CTE as (select lag(name) over (order by name) as name1
              ,lag(salary) over (order by name) as salary1
              , * 
              from #table)

delete from cte where name = name1 and salary = salary1
APH
  • 4,109
  • 1
  • 25
  • 36
3

You can use Common Table Expression combined with ROW_NUMBER() like this (This is the best way to delete duplicates):

WITH CTE AS(
   SELECT t.name,t.salary
          ROW_NUMBER() OVER(PARTITION BY t.name,t.salary ORDER BY (SELECT 1)) as rn
   FROM YourTable t
)
DELETE FROM CTE WHERE RN > 1

ROW_NUMBER() will assign each group randomly ranking, only one will get the rank 1 , and every thing else will be deleted.

EDIT: I can suggest something else with out the use of ROW_NUMBER() :

SELECT distinct t.name,t.salart
INTO TEMP_FOR_UPDATE
FROM YourTable t;

TRUNCATE TABLE YourTable ;

INSERT INTO YourTable 
SELECT * FROM TEMP_FOR_UPDATE;

DROP TEMP_FOR_UPDATE;

This will basically create a temp table containing distincted values from your table, truncate your table and re insert the distincted values into your table.

sagi
  • 40,026
  • 6
  • 59
  • 84
1
  1. Select data from your table using group by name , salary (or distinct).
  2. Insert into temp table.
  3. Delete data in original
  4. Copy data from temp table to your original table
dcieslak
  • 2,697
  • 1
  • 12
  • 19
0

In oracle you can use as below

Delete from table where rowid not in (select max(rowid) from test group by name, salary);

Temruzinn
  • 30
  • 3
  • 1
    The question is about SQL Server. – Zein Makki Jun 01 '16 at 06:16
  • otherwise you follow as below Create temporary table emp_temp As Select Distinct name, salary From emp_temp; Truncate table emp; Insert into emp Select * From emp_temp; – Temruzinn Jun 01 '16 at 06:37
  • people are so eager to give negative flag.. i agree the answer is irrelevant but @Temruzinn already said its for oracle...I am getting rid of at least one negative – danD Nov 07 '19 at 20:46