2013-06-05 95 views
3

我在表中有重复记录。我需要能够识别唯一的唯一标识符,所以我可以从表中删除它。如何识别重复记录的唯一标识符?

我知道有一个重复的唯一方法是从列subjectdescription所以如果至少有2个相同的主题和相同的描述,我需要删除一个,并留下一个。

所以我能够得到重复记录的列表,但我无法获得唯一标识符以便能够删除它。

这是我所做的识别重复记录。

SELECT 
    p.accountid, p.subject, p.description, count(*) AS total 
FROM 
    activities AS p 
WHERE  
    (p.StateCode = 1) AND p.createdon >= getdate()-6 
GROUP BY 
    p.accountid, p.subject, p.description 
HAVING 
    count(*) > 1 
ORDER BY 
    p.accountid 

有一列record_id其中包含每个记录的唯一标识符。但如果我在我的select语句中添加了record_id,那么我得不到结果,因为它不可能具有重复的唯一标识符

如何使用SQL Server获得record_id

注:RECORD_ID不是一个整数,它是像 “D32B275B-0B2F-4FF6-8089-00000FDA9E8E”

感谢

回答

4

一个不错的功能,我喜欢SQL Server与updatedelete语句使用热膨胀系数的。

您正在查找重复记录,并且可能想保留最低或最高的record_id。你可以得到的计数和ID使用CTE和窗口功能,以保持:

with todelete as (
    SELECT p.accountid, p.subject, p.description, 
      COUNT(*) over (partition by p.accountid, p.subject, p.description) as total, 
      MIN(record_id) over (partition by p.accountid, p.subject, p.description) as IdToKeep 
    FROM activities AS p 
    WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
    ) 
delete from todelete 
    where total > 1 and record_id <> IdToKeep; 

最后where条款只是用逻辑来选择合适的行删除。

我要补充,如果你只是想将被删除的列表,你可以使用类似的查询:

with todelete as (
    SELECT p.accountid, p.subject, p.description, 
      COUNT(*) over (partition by p.accountid, p.subject, p.description) as total, 
      MIN(record_id) over (partition by p.accountid, p.subject, p.description) as IdToKeep 
    FROM activities AS p 
    WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
    ) 
select * 
from todelete 
where total > 1 and record_id <> IdToKeep; 

over功能指示功能正被用作窗口函数。这个想法很简单。 Count(*) over返回partition子句中字段值相同的所有记录的计数。这与聚合函数非常相似,不同之处在于您可以获得每一行的值。这个类的功能非常强大,我建议你多了解它们。

+0

谢谢你的回答,但RECORD_ID不是整数它是什么:

;with recordsToDelete as ( SELECT recordId ,Row_Number() OVER(partition p.subject, p.description) as rowNum FROM activities AS p ) select * from recordsToDelete where rowNum > 1 

如果这看起来是正确的,你可以将其替换选择像这样“D32B275B-0B2F-4FF6-8089-00000FDA9E8E”我得到这个错误与第二个代码操作数数据类型uniqueidentifier对于最小操作符无效。 – Mike

+0

@Mike。 。 。在这种情况下,你可以使用'MIN(cast(record_id as varchar(255)))。 。 .'。 MIN()会返回一个任意的值来保存。那是问题吗?如果是这样,你将如何选择记录ID保留哪些? –

+0

非常感谢你的工作,但是请你向我解释一下干什么和分区?谢谢 – Mike

0

也许这样的事情?

SELECT max(p.record_id), p.accountid, p.subject, p.description, count(*) AS total 
FROM activities AS p 
WHERE (p.StateCode = 1) AND p.createdon >= getdate()-6 
GROUP BY p.accountid, p.subject, p.description 
HAVING count(*) > 1 
ORDER BY p.accountid 
0

对我来说,你需要先做一个内部查询,然后连接到较大的表来获得你想要的。

SELECT ALL 
    * 
FROM (SELECT p.accountid 
    FROM activities AS p 
    WHERE p.statecode = 1 AND p.createdon >= getdate()-6 
    GROUP BY p.accountid 
    HAVING count(*) > 1) AS x 
JOIN activities AS a ON x.accountid = a.accountid 
ORDER BY p.accountid 
0

试试这个:

delete from recordsToDelete 
    where rowNum > 1