Поиск повторяющихся значений в таблице, где все столбцы не совпадают - PullRequest
2 голосов
/ 20 мая 2019

Я работаю с набором данных в таблице. Для простоты у меня есть таблица, как показано ниже, с некоторыми примерами данных:

enter image description here

Некоторые данные в этой таблице взяты из другого источника, такие данные имеют cqmRecordID != null

Мне нужно найти дубликаты значений в этой таблице и удалить дубликаты, полученные из другого источника (с cqmRecordID) Запись считается дубликатом, если они имеют одинаковые значения для этих столбцов:

  • [Имя]
  • Cast ([CreatedDate] as Date)
  • [CreatedBy]

Таким образом, в приведенных выше примерах данных запись № 5 и запись № 6 будут считаться дубликатами.

В качестве решения я предложил следующие два запроса:

Запрос № 1:

 select * from (
  select recordid, cqmrecordid, ROW_NUMBER() over (partition by name, cast(createddate as date), createdby 
                                                   order by cqmrecordid, recordid) as rownum
  from vmsNCR  ) A
  where cqmrecordid is not null   
  order by recordid

enter image description here

Запрос № 2:

  select A.recordID, A.cqmRecordID, B.RecordID, B.cqmRecordID 
  from vmsNCR A 
  join vmsNCR B
    on A.Name = B.Name 
    and cast(A.CreatedDate as date) = cast(B.CreatedDate as date) 
    and A.CreatedBy = B.CreatedBy
    and A.RecordID != B.RecordID 
    and A.cqmRecordID is not null 
  order by A.RecordID

enter image description here

Есть ли лучший подход к этому? Является ли один лучше, чем другой по производительности?

Ответы [ 3 ]

1 голос
/ 20 мая 2019

Если вы хотите извлечь все строки без дубликатов, то:

select t.*  -- or all columns except seqnum
from (select t.*,
             row_number() over (partition by name, cast(createddate as date), createdby
                                order by (case when cqmRecordId is not null then 1 else 2 end)
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

Если вы хотите повысить производительность, создайте столбцы, а затем индекс:

alter table t add cqmRecordId_flag as (case when cqmRecordId is null then 0 else 1 end) persisted;
alter table t add createddate_date as (cast(createddate as date)) persisted;

И затемindex:

create index idx_t_4 on t(name, createddate_date, createdby, cqmRecordId_flag desc);

EDIT:

Если вы на самом деле просто хотите удалить значения NULL из таблицы, вы можете использовать:

delete t from t
    where t.cqmRecordId is null and
          exists (select 1
                  from t t2
                  where t2.name = t.name and
                        convert(date, t2.createddate_date) =convert(date, t.createddate_date) and
                        t2.createdby = t.createdby and
                        t2.cqmRecordId is not null
                 );

Вы можетеиспользуйте ту же логику с select, чтобы просто выбрать дубликаты.

0 голосов
/ 20 мая 2019

Попробуйте ниже Запрос, это может работать для Вас

;WITH TestCTE
AS
(
   SELECT *,ROW_NUMBER() OVER(
              PARTITION BY [Name],Cast([CreatedDate] as Date),[CreatedBy] 
              ORDER BY RecordId
            ) AS RowNumber
)
DELETE FROM TestCTE
WHERE RowNumber > 1
0 голосов
/ 20 мая 2019

Используйте приведенный ниже код для устранения дубликатов

;WITH CTE
AS
(
   SELECT ROW_NUMBER() OVER(
              PARTITION BY [Name],Cast([CreatedDate] as Date),[CreatedBy] 
              ORDER BY cqmRecordId
           ) AS Rnk
   ,*
)
DELETE FROM CTE
WHERE Rnk <> 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...