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:
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:
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
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
Y a-t-il une meilleure approche? L'un est-il meilleur que l'autre en termes de performances?
3 Réponses :
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
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);
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;
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
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
EXPLAINet des informations sur la taille de la table, l'index, les performances en temps réel, le temps souhaité, etc.Slowest 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?