Поиск дубликатов: GROUP BY и DISTINCT дают разные ответы - PullRequest
1 голос
/ 31 мая 2019

Я просмотрел все вопросы о группах по группам и по-разному, и они кажутся разными с точки зрения разрешения агрегатных функций, но никто из них не ответил на мой вопрос ... так что вот так ...

Iу меня есть таблица базы данных с 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 дубликатов или 47,355 дубликатов?И как только я разобрался, что правильно, мне нужно удалить дублирующиеся значения из таблицы ... Обычно я делал бы это, чтобы удалить значения с помощью fk, но я не могу получить правильный синтаксис для нескольких fksчерез 2+ таблицы.

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

Любая помощь с этим будет принята с благодарностью.

Заранее спасибо!

1 Ответ

2 голосов
/ 31 мая 2019

Ваша логика подсчета отключена, и моя тоже была, пока я не нашел простой пример, чтобы лучше понять ваш вопрос.Представьте себе простую таблицу с одним столбцом: text:

text
----
A
B
B
C
C
C

Выполнение SELECT COUNT(*) дает всего 6 записей, как и ожидалось.SELECT DISTINCT text возвращает 3 записи, для A,B,C.Наконец, SELECT text с HAVING COUNT(*) > 1 возвращает только две записи для групп B и C.

Ни одно из этих чисел не суммируется вообще.Проблема здесь в том, что отдельный выбор также возвращает записи, которые не дублируются, в дополнение к записям, которые являются дубликатами.Кроме того, данная дублирующаяся запись может встречаться на больше , чем два раза.Ваше текущее сравнение - это что-то вроде яблок и апельсинов.

Редактировать:

Если вы хотите удалить все дубликаты в таблице из шести столбцов, оставив только одну отдельную запись из всехстолбцы, затем попробуйте использовать удаляемый 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;
...