2016-06-01 60 views
3

我不想使用ROW_NUMBER()函數(SQL Server)的刪除重複記錄,而不使用ROW_NUMBER()函數

實例來刪除重複記錄:表數據如下:

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

刪除後重復記錄 表應該包含數據是這樣的:

name  salary 
----------------- 
Husain 20000.00 
Munavvar 50000.00 
+5

你至少有一個ID? – user3185569

+5

使用'Row_Number()'時出現什麼問題? – Raj

+1

不只兩列(姓名,工資)。面試官在最近的採訪中問我這個問題。 – Munavvar

回答

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

+0

謝謝Martin的回答。 – Munavvar

2

您可以使用Common Table Expression與結合這樣的(這是刪除重複的最佳方式):

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; 

這基本上都會創建一個包含從表中distincted值的臨時表,截斷你的表並重新插入distincted值進入你的桌子。

+3

**沒有**的哪一部分你不明白? – Raj

+0

CTE是什麼特別的東西? – miltonb

+0

@Raj只是因爲OP說不使用'ROW_NUMBER()'並不是一個不好的解決方案。 –

-2

在oracle中,你可以使用如下

從表 請刪去不ROWID中(選擇測試組最高(ROWID)的名稱,工資);從表中使用group by name , salary(或 distinct

+1

問題是關於SQL Server。 – user3185569

+0

否則你按照如下創建臨時表emp_temp爲 選擇不同的名稱,工資 從emp_temp; 截斷表emp; 插入到emp 選擇* 從emp_temp; – Temruzinn

1
  1. 選擇數據。
  2. 插入臨時表。
  3. 從臨時表中原來
  4. 將數據複製到您的原始表
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