删除重复记录而不使用ROW_NUMBER()函数

时间:2016-06-01 06:02:59

标签: sql sql-server

我想在不使用ROW_NUMBER()函数(SQL Server)的情况下删除重复记录

示例:包含以下数据的表:

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

删除重复记录后 table应该包含这样的数据:

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

5 个答案:

答案 0 :(得分:6)

因为这个问题的动机似乎是学术兴趣而不是实际用途......

该表没有主键,但未记录的伪列%%physloc%%可以提供替代。

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)

实际上,你不应该使用上面的just use row_number,因为它更有效并且有文档记录。

Data Explorer Demo

答案 1 :(得分:4)

另一个(学术)选项,具体取决于您使用的SQL服务器版本:

;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

答案 2 :(得分:2)

您可以将Common Table Expression与此ROW_NUMBER()结合使用(这是删除重复项的最佳方法):

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()将为每个组分配随机排名,只有一个会获得排名1,其他所有内容都将被删除。

编辑:我可以使用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;

这基本上会创建一个包含表中不同值的临时表,截断表并重新将差异值插入表中。

答案 3 :(得分:1)

  1. 使用group by name , salary(或 distinct)。
  2. 插入临时表。
  3. 删除原始数据
  4. 将数据从临时表复制到原始表

答案 4 :(得分:-2)

在oracle中你可以使用如下

从表中删除 其中rowid不在(从名称,薪水中选择测试组的max(rowid));