查找重复项:GROUP BY和DISTINCT给出不同的答案

时间:2019-05-31 09:33:08

标签: sql sql-server duplicates

我仔细研究了所有有关分组依据和与众不同的问题,它们在允许聚合函数方面似乎有所不同,但是它们都没有回答我的问题...所以去了。

我有一个包含126266行数据的数据库表,每个完整行应该是唯一的,但是我没有使用行号。 我正在尝试查找此表中的所有重复值(据我所知它们存在),然后将其删除。这些列都不是聚合。

表格:

CREATE TABLE [dbo].[DBAScanResults](
    [ScanNumber] [float] NOT NULL,
    [DB_ID] [bigint] NOT NULL,
    [PluginID] [bigint] NOT NULL,
    [PluginID_Version] [bigint] NOT NULL,
    [Result] [nvarchar](50) NULL,
    [ActualValue] [nvarchar](max) NULL

我有外键:ScanNumber,DB_ID,PluginID_Version。每个相关的主键都在不同的表上。 (所以我的数据库当前是四个表)

如果我按分组依据,它会给我12745行,这是我的重复行:

Select top 1000000 [ScanNumber]
      ,[DB_ID]
      ,[PluginID]
      ,[PluginID_Version]
      ,[Result]
      ,[ActualValue]
  FROM [ITSecMaster].[dbo].[DBAScanResultsNew]
  group by [ScanNumber]
      ,[DB_ID]
      ,[PluginID]
      ,[PluginID_Version]
      ,[Result]
      ,[ActualValue]
      HAVING COUNT(*) >1 

如果我执行不同的( Select distinct * from [dbo].[DBAScanResults])操作,则会得到78,871行,我猜这是我唯一的无重复行数。我的问题是12745 + 78871不等于126226 ...

那么哪一个实际上是正确的?我有12745个重复项,还是47355个重复项? 一旦确定出正确的值,我便需要从表中删除重复的值...通常,我会用fk删除值,但是我无法正确获取多个fks的语法超过2张桌子。

DELETE a   
FROM DBAScanResults a 
INNER JOIN DBAScanDate b 
ON a.ScanNumber = b.ScanNumber 
WHERE (expression) 

任何对此的帮助将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:2)

您的计数逻辑已关闭,我的也是如此,直到我提出一个简单的示例以更好地理解您的问题。想象一个只有一列text的简单表:

text
----
A
B
B
C
C
C

运行SELECT COUNT(*)仅产生6条记录,如预期的那样。 SELECT DISTINCT textA,B,C返回3条记录。最后,SELECT textHAVING COUNT(*) > 1仅返回两个记录,分别属于BC组。

这些数字都没有加起来。这里的问题是,除了重复记录外,唯一选择还返回重复的记录。同样,给定的重复记录可能发生的次数多于两次。您当前的比较有点像苹果与橘子。

编辑:

如果要删除六列表中的所有重复项,而在所有列中仅保留一条不同的记录,请尝试使用可删除的CTE:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ScanNumber, DB_ID, PluginID,
                                        PluginID_Version, Result, ActualValue
                               ORDER BY (SELECT NULL)) rn
    FROM DBAScanResults
)

DELETE
FROM cte
WHERE rn > 1;