删除重复...用空值

问题描述:

在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将不起作用,因为重复项具有不同的时间戳。

这应该这样做:

;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

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

试试这个

;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 

我的解决办法:

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