Dédoublonner

Messages postés
393
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
29 septembre 2008
-
Messages postés
393
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
29 septembre 2008
-
Salut,

Je veut dédoublonner une table (je suis sous SQL server)

Donc dans un premier temps :
recherche des doublons et mise dans une table temporaires :
INSERT INTO %Table(MM_DOUBLON)
 SELECT *
  FROM %Table(MM_LIGNE)
  GROUP BY PROCESS_INSTANCE
  ,MM_REF1
  ,MM_REF2 
  HAVING COUNT(*) > 1
Cette requete marche

ensuite je delete les enregistrement de ma table temporaires dans la deuxieme table
DELETE
  FROM PS_MM_LIGNE
 WHERE EXISTS (
 SELECT t2.MM_REF1
 , t2.MM_REF2 
  FROM PS_MM_DOUBLON t2 ,PS_MM_LIGNE t1
 WHERE t1.MM_REF1 = t2.MM_REF1
   AND t1.MM_REF2 = t2.MM_REF2 
  GROUP BY t2.MM_REF1 , t2.MM_REF2
  HAVING COUNT(*) > 1)
Cette requete ne marche pas aidez moi

puis je réinsère mes donnés
INSERT INTO %Table(MM_LIGNE)
 SELECT *
  FROM %Table(MM_DOUBLON)
Cette requete marche

++

"Aucun de nous ne sait ce que nous savons tous, ensemble." Lao Tseu inventeur du "copier coller" [8D]

6 réponses

Messages postés
259
Date d'inscription
mercredi 3 mai 2006
Statut
Modérateur
Dernière intervention
11 janvier 2010
7
Salut,

Première chose, dans une clause EXISTS pas la peine de mettre quelque chose dans la clause SELECT, SELECT * est très bien dans ce cas.

Deuxièmement, la requête de suppression, doit supprimer tous les enregistrements qui ont un doublon, au lieu de retirer seulement les enregistrement en trop...

Comme c'est sur Access, je ne connais pas la manière idéale de faire.
En général dans la table à dédoublonner on ajoute un champ, type auto-incrément (s'il y a déjà une clef primaire sur la table on utilisera celle-ci), la requête donnerait dans ce cas :

DELETE
  FROM PS_MM_LIGNE
 WHERE ChampInc IN
(SELECT MAX(ChampInc)
  FROM PS_MM_DOUBLON t2 ,PS_MM_LIGNE t1
 WHERE t1.MM_REF1 = t2.MM_REF1
   AND t1.MM_REF2 = t2.MM_REF2 
  GROUP BY t2.MM_REF1 , t2.MM_REF2
  HAVING COUNT(*) > 1))

Ici on part du principe qu'il n'y a que des doublons (pas de triples, etc.), s'il y en avait il faudrait réexecuter une nouvelle fois la requête.

Christian Robert - Winwise
http://blogs.developpeur.org/christian/
MCT - Database Development / Database Administration
Messages postés
393
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
29 septembre 2008

Salut,


Merci de ta réponse


Pour l'utilisation d'une clef unique j'y avais pensé (merci google) malheuresment je n'ai pas les droits necessaire pour faire un alter table (il n'y a pas de clef unique dans la base) de plus je ne suis pas sous acces mais sur MS SQL SERVER 2005 (ma souris a du glisser quand j'ai choisi le theme je trouve ca byzarre d'ailleurs...)

++

"Aucun de nous ne sait ce que nous savons tous, ensemble." Lao Tseu inventeur du "copier coller" [8D]
Messages postés
259
Date d'inscription
mercredi 3 mai 2006
Statut
Modérateur
Dernière intervention
11 janvier 2010
7
Ah ok... Ca devrait simplifier les choses du coups...
Essaye çà :



DELETE TOP (1)
  FROM PS_MM_LIGNE
 WHERE ChampInc IN
(SELECT MAX(ChampInc)
  FROM PS_MM_DOUBLON t2 ,PS_MM_LIGNE t1
 WHERE t1.MM_REF1 = t2.MM_REF1
   AND t1.MM_REF2 = t2.MM_REF2 
  GROUP BY t2.MM_REF1 , t2.MM_REF2
  HAVING COUNT(*) > 1))



Ca doit supprimer un enregistrement à la fois. Tu mets cette requête dans une jolie boucle.
Une fois qu'elle ne supprime plus rien, c'est qu'il n'y a plus de doublons.

Christian Robert - Winwise
http://blogs.developpeur.org/christian/
MCT - Database Development / Database Administration
Messages postés
393
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
29 septembre 2008

Comme je l'ai dit au message d'avant je n'ai pas de clef primaire ou unique dans cette table c'est donc mon gros soucis il ya juste des données brute

"Aucun de nous ne sait ce que nous savons tous, ensemble." Lao Tseu inventeur du "copier coller" [8D]
Messages postés
259
Date d'inscription
mercredi 3 mai 2006
Statut
Modérateur
Dernière intervention
11 janvier 2010
7
Oui, mais çà n'est pas grave dans ce cas, le TOP dans le DELETE supprime le premier enregistrement ui lui tombe sous la main.

Et je m'étais trompé de requête dans mon copier / coller...

Avec ceci çà devrait résoudre le pb.

DECLARE

@count intSET

@count
= 1
WHILE

@count
!= 0
BEGIN
DELETE
TOP
(1
)
FROM PS_MM_LIGNE

WHERE
EXISTS
(

SELECT
*
FROM PS_MM_DOUBLON t2
,PS_MM_LIGNE t1

WHERE t1
.MM_REF1
= t2
.MM_REF1

AND t1
.MM_REF2
= t2
.MM_REF2

GROUP
BY t2
.MM_REF1
, t2
.MM_REF2

HAVING
COUNT(*)
> 1
)
SET @count
=
@@ROWCOUNT
END

Christian Robert - Winwise
http://blogs.developpeur.org/christian/
MCT - Database Development / Database Administration
Messages postés
393
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
29 septembre 2008

Hum le probleme c'est que quand je fait ca :
DELETE

FROM PS_MM_LIGNE

WHERE
EXISTS
(

SELECT
*
FROM PS_MM_DOUBLON t2
,PS_MM_LIGNE t1

WHERE t1
.MM_REF1
= t2
.MM_REF1

AND t1
.MM_REF2
= t2
.MM_REF2

GROUP
BY t2
.MM_REF1
, t2
.MM_REF2

HAVING
COUNT(*)
> 1
)

Ca me supprime tout les enregistrements (c'est pas tres cool lol)
(Ma table est plus complexe que juste MM_REF1 et MM_REF2, j'ai 7 champs à vérifier avant de dire qu'il y a un doublon)
Par contre j'ai réussi a avoir ce que je voulai sur une autre requete masi c'est pas tres jolie ....

SELECT *
FROM PS_MM_LIGNE

WHERE MM_REF1 IN (

   SELECT MM_REF1
   FROM PS_MM_DOUBLON t2
,PS_MM_LIGNE t1

   WHERE t1
.MM_REF1
= t2
.MM_REF1 

   AND t1
.MM_REF2
= t2
.MM_REF2 

   GROUP
BY t2
.MM_REF1
, t2
.MM_REF2

   HAVING
COUNT(*)
> 1
)
and MM_REF2 IN (
   SELECT MM_REF2

   FROM PS_MM_DOUBLON t2
,PS_MM_LIGNE t1

   WHERE t1
.MM_REF1
= t2
.MM_REF1 

   AND t1
.MM_REF2
= t2
.MM_REF2 

   GROUP
BY t2
.MM_REF1
, t2
.MM_REF2

   HAVING
COUNT(*)
> 1
)

J'ai l'impression que c'est le EXISTSqui foire  J'ai du faire une connerie ....

++
"Aucun de nous ne sait ce que nous savons tous, ensemble." Lao Tseu inventeur du "copier coller" [8D]