删除基于Group By - SQL的重复项

时间:2015-04-28 08:50:38

标签: sql sql-server group-by duplicate-data

编辑:我想我现在有了解决方案,但需要做一些更有意义的检查......

DELETE TBLFIRE_TEMP3 FROM TBLFIRE_TEMP3
LEFT OUTER JOIN (
   SELECT MIN(FireNo) as FireNo, ActionRef, FRADate, FIREUPRN
   FROM TBLFIRE_TEMP3 
   GROUP BY ActionRef, FRADate, FIREUPRN
) as KeepRows ON
   TBLFIRE_TEMP3.FireNo = KeepRows.FireNo
WHERE
   KeepRows.FireNo IS NULL

- ###############上一条评论###############

我有一个重复的表(基于三列)。我可以通过执行以下操作找到它们并查看它们,然后只是想删除重复项(即所有计数(*)结果都是' 1')

SELECT COUNT(*),ActionRef, FRADate, FIREUPRN
FROM TBLTempTable
GROUP BY ActionRef, FRADate, FIREUPRN

所以我可以看到这些群体发生的次数。我想要做的是删除重复项。我已经尝试了以下但它删除了每一行,甚至是单数:

DELETE a FROM TblTempTable a JOIN
(
  SELECT ActionRef, FRADate, FIREUPRN
    FROM TblTempTable 
   GROUP BY ActionRef, FRADate, FIREUPRN
) d 
   ON (a.ActionRef = b.ActionRef
  AND a.FRADate = b.FRADate
AND a.FIREUPRN = b.FIREUPRN)

基于代码,我看了指南,我相信我很接近,但目前它删除了所有内容。

参考文献: SQL- How can I remove duplicate rows? GROUP BY does not remove duplicates

- 这些是MySQL所以最终不相关:

select and delete rows within groups using mysql Find duplicate records in MySQL

2 个答案:

答案 0 :(得分:6)

一个简单的解决方案是使用带ROW_NUMBER的CTE:

WITH Data AS
(
    SELECT RN  = ROW_NUMBER() OVER (PARTITION BY ActionRef, FRADate, FIREUPRN
                                    ORDER BY FRADate ASC),
           Cnt = COUNT(*) OVER (PARTITION BY ActionRef, FRADate, FIREUPRN),
           ActionRef, FRADate, FIREUPRN
    FROM TBLTempTable
)
DELETE FROM Data
WHERE RN > 1

这将删除除一个以外的所有内容,它会保留最早的FRADate。您需要更改ORDER BY中的ROW_NUMBER才能更改此逻辑。

CTE的一个优点是您可以轻松更改它以查看您要删除(或更新)的内容。因此,您只需将DELETE FROM Data替换为SELECT * FROM Data

答案 1 :(得分:1)

还有一种更简单的可读性方法:

;WITH DEDUPE AS (
SELECT ROW_NUMBER() OVER(
    PARTITION BY ActionRef, FRADate, FIREUPRN
        ORDER BY (SELECT 1)) AS RN
FROM TBLTempTable)
DELETE FROM DEDUPE
WHERE RN != 1

我们每天都在使用这个确切的脚本。如果要根据日期列等保留较新的行,可以将ORDER BY子句更改为任何列。