1
votes

Recherche de valeurs en double dans une table où toutes les colonnes ne sont pas identiques

Je travaille avec un ensemble de données dans une table. Pour plus de simplicité, j'ai le tableau ci-dessous avec quelques exemples de données:

 entrez la description de l'image ici

Certaines des données de ce tableau proviennent d'une source différente, comme des données sont ceux qui ont cqmRecordID! = null

J'ai besoin de trouver les valeurs en double dans ce tableau et de supprimer les doublons provenant de l'autre source (ceux avec un cqmRecordID) Un enregistrement est considéré en double s'il a les mêmes valeurs pour ces cols:

  • [Nom]
  • Diffuser ([CreatedDate] en tant que date)
  • [CreatedBy]

Donc, dans les exemples de données que j'ai ci-dessus, l'enregistrement n ° 5 et l'enregistrement n ° 6 seraient considérés comme des doublons.

En tant que solutions, j'ai proposé ces deux requêtes:

Requête n ° 1:
  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

entrez la description de l'image ici

Requête n ° 2:

 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

entrez la description de l'image ici

Y a-t-il une meilleure approche? L'un est-il meilleur que l'autre en termes de performances?


6 commentaires

Alors, quel est le problème avec ces requêtes?


@JuanCarlosOropeza n'ayant pas de problème avec la requête .. mais se demandant simplement si c'est la meilleure approche .. ce n'est que des exemples de données .. j'aurai un grand ensemble de données.


Les questions sur les performances doivent inclure EXPLAIN et des informations sur la taille de la table, l'index, les performances en temps réel, le temps souhaité, etc. Slow est un terme relatif et nous avons besoin d'une valeur réelle pour comparer .


{1,3} n'est-il pas également en double?


@JuanCarlosOropeza non .. ceux-ci ne seront pas des doublons .. parce que je ne considère qu'un enregistrement comme dupliqué s'il provient de la source de données différente (une avec cqmRecordNumber non nul)


Pouvez-vous avoir un enregistrement dupliqué non nul sans enregistrement nul? Donc, la seule donnée n'est pas nulle, donc n'est-elle pas vraiment dupliquée?


3 Réponses :


0
votes

Utilisez le code ci-dessous pour éliminer les doublons

;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


0 commentaires

1
votes

Si vous voulez récupérer toutes les lignes sans doublons, alors:

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
                 );

Si vous voulez des performances, créez une colonne puis un index:

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


6 commentaires

Peut-être voulez-vous utiliser rank () au lieu de row_number () en cas de doublons multiples?


Cela apporte aussi celui sans doublons.


@JuanCarlosOropeza. . . Je suppose que l'OP veut vraiment récupérer les lignes sans doublons, mais j'ai mis à jour la réponse.


En regardant le résultat du désir OP (sur les photos), il renvoie {5,6} ce qu'il considère comme les doublons


Il veut supprimer les doublons non nuls. La logique est donc inversée.


J'ai changé la requête que vous aviez un peu en vue d'obtenir le résultat que je veux .. comme Juan l'a mentionné, je veux seulement que 5 et 6 reviennent en tant que doublons ... sélectionnez t. * - ou toutes les colonnes sauf seqnum de (sélectionnez t. *, row_number () over (partition by name, cast (createddate as date), createdby order by (cas où cqmRecordId n'est pas nul puis 1 else 2 end) desc) as seqnum from t) t where seqnum! = 1;



0
votes

Essayez ci-dessous. Recherchez cela pourrait fonctionner pour vous

;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 commentaires