1

在MS SQL Server中我試圖從表中刪除帶有空值的重複項。哼哼哼。很多很多NULL s。底線是我需要保留有或沒有NULL s的任何重複記錄的一個副本。我基本上希望NULL在操作期間像正常記錄一樣操作,值爲「NULL」,然後再回到實際NULL。這可能嗎?有一個更簡單的解決方案嗎?刪除重複...用空值

Table1樣子:

UID  Data1 Data2 
1   A  NULL   
2   A  NULL  
3   B  abc  
4   B  abc  
5   C  NULL  
6   D  ghj 

我希望命令扔掉線2和4,並保持休息。 (SELECT用於測試。)

;SELECT UID, Data1, Data2 
FROM Table1 AS T 
WHERE NOT EXISTS (
    SELECT 1 
    FROM table1 AS T2 
    WHERE 
     T2.Data1 = T.Data1 
     AND T2.Data2 = T.Data2 
     AND T2.UID >= T.UID 
    ) 
    AND Data1 IS NOT NULL 

注意:SELECT DISTINCT將不起作用,因爲重複項具有不同的時間戳。

回答

3

這應該這樣做:

;WITH CTE AS 
(
    SELECT *, 
      RN = ROW_NUMBER() OVER(PARTITION BY Data1,Data2 ORDER BY UID) 
    FROM table1 
) 
DELETE 
--SELECT * 
FROM CTE 
WHERE RN > 1 

修訂如下評論

好吧,如果您有問題需要刪除的行的金額,那麼你可以嘗試創建一個查找表要刪除的Id,然後執行批量刪除(儘管如此,您將不得不測試批量行數量)。這是一個想法(假設UID是PK):

;WITH CTE AS 
(
    SELECT *, 
      RN = ROW_NUMBER() OVER(PARTITION BY Data1,Data2 ORDER BY UID) 
    FROM table1 
) 
SELECT [UID] 
INTO RowsToDelete 
FROM CTE 
WHERE RN > 1; 

CREATE INDEX I_UID ON RowsToDelete([UID]); 

WHILE 1=1 
BEGIN 
    DELETE TOP (10000) 
    FROM table1 T 
    INNER JOIN RowsToDelete L 
      ON T.[UID] = L.[UID] 
    IF @@ROWCOUNT < 10000 BREAK; 
END 
+0

可憐的電腦正在融化,但它工作! – user2366153 2013-05-14 15:13:30

+0

@ user2366153哎喲,抱歉讓你的電腦熔化 – Lamak 2013-05-14 15:26:45

+0

Soo ..更新到問題。我不能在沒有首先將它作爲SELECT進行測試的情況下運行它,並且在幾分鐘後拋出System.outofmemory。任何首先要做排序的方法,然後以大約1000萬條記錄的「塊」的方式來做到這一點? – user2366153 2013-05-14 18:43:59

0

SELECT DISTINCT Data1, Data2 FROM Table1不夠嗎?

+0

這樣做是可以選擇,但如果他/她正試圖刪除表中的重複項,不。 – 2013-05-14 15:02:39

+0

可悲的是,重複項具有不同的時間戳,但在其他方面是相同的。 – user2366153 2013-05-14 15:03:00

+0

啊是的 - 我的錯,因爲沒有正確閱讀這個問題。 – 2013-05-14 15:05:36

0

試試這個

;WITH uTable AS (
    SELECT UID, Data1, Data2, ROW_NUMBER() OVER (PARTITION BY Data1,Data2 ORDER BY UID DESC) as rownum 
    FROM Table1 AS T) 

    SELECT UID, Data1, Data2 
    FROM uTable 
    WHERE rownum = 1 
0

我的解決辦法:

declare @data TABLE (UID int, Data1 char(1), Data2 Char(3)) 

-- Your example data 
INSERT INTO @data (UID, Data1, Data2) 
VALUES (1,'A',NULL),(2,'A',NULL),(3,'B','abc'),(4,'B','abc'),(5,'C',NULL),(6,'D','ghj') 

DELETE FROM @data WHERE UID in (
    SELECT UID FROM (
    SELECT UID, ROW_NUMBER() OVER(PARTITION BY Data1,Data2 ORDER BY UID) as RowNo FROM @data 
) d WHERE d.rowNo>1 
) 

SELECT UID, Data1, Data2 FROM @data