Précédent   Forum du club des développeurs et IT Pro > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 08/01/2013, 12h20   #1
Splasher
Invité de passage
 
Homme
Étudiant
Inscription : janvier 2013
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2013
Messages : 4
Points : 0
Points : 0
Par défaut Enlever les doublons

Bonjour,

Je suis confronté a un problème, en apparence simple mais qui me pose beaucoup de soucis (principalement parce que je suis pas très à l'aise avec le SQL également).
J'ai plusieurs base a "nettoyer", elles ont toute une architecture différentes (autant sur le nombre de variable, que sur leurs type ou leurs taille).
Pour schématiser le problème, j'ai créer une base de test simple :

Code :
1
2
3
4
5
6
7
A   B   C   D   // Quatre VARIABLES
 
A1  B1  C1  D1  // Quatre valeurs
A1      C1  D1
    B1  C1  D1
        C1  
A1  B1  C1
Comme vous pouvez le voir, ma table est composé de ligne complète et quasiment identique mais auquel il manque des champs.
Je peux pas les garder dans ma base, ces lignes représentent juste une perte d'information.
J'arrive a traiter le cas où deux lignes sont strictement identique (doublons parfait) et à supprimer toutes ces lignes.

J'ai naïvement fait un algorithme qui compare chaque variable avec les variables des lignes suivantes mais l'algo est absolument pas évolutif et absolument pas pratique (pour 4 variables, 4*4 IF différents ...)
Il me faudrait un algo qui puisse se déplacer de variables en variables sans utiliser leurs noms et qui s'arrête quand la ligne ne contient plus de variable à comparer (comme une boucle FOR pour parcourir un tableau) mais j'ai aucunes idées de comment faire ...

Si vous avez une idée de comment éclairer ma lanterne, je vous remercie d'avance
( et si jamais je suis pas très clair dans mes explications, je peux toujours ré expliquer )
Splasher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 12h55   #2
jkofr
Membre éprouvé
 
Avatar de jkofr
 
Homme Jacques Kostic
Senior Consultant DBA (Trivadis SA)
Inscription : octobre 2006
Messages : 369
Détails du profil
Informations personnelles :
Nom : Homme Jacques Kostic
Âge : 44
Localisation : Suisse

Informations professionnelles :
Activité : Senior Consultant DBA (Trivadis SA)
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 369
Points : 482
Points : 482
Envoyer un message via MSN à jkofr
CREATE TABLE temptable AS SELECT DISTINCT nvl (var1,'vide'),nvl (var2,'vide'),nvl (var3,'vide'),nvl (var4,'vide') FROM tatable;

Tu contrôle tes données.

TRUNCATE tatable;

INSERT INTO tatable SELECT * FROM temptable;

jko
__________________
OCP 11g, RAC and Performance & Tuning Expert 11g
RMAN Backup & Recovery, Data Guard and Grid Control
jkofr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 17h35   #3
Splasher
Invité de passage
 
Homme
Étudiant
Inscription : janvier 2013
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2013
Messages : 4
Points : 0
Points : 0
Donc si j'ai bien compris, l'idée est de créer une table contenant tout ce qui est différent de la ligne :
nvl (var1,'vide'),nvl (var2,'vide'),nvl (var3,'vide'),nvl (var4,'vide')

Mais ca me reviens davantage a enlever ce qui est différent plus que la perte d'information en soit, il me semble.

Imaginons :

Code :
1
2
3
4
5
6
7
A   B   C  D   // Quatre VARIABLES
 
     B1 C1 D1  // Quatre valeurs
A1      C1 D1
     B1 C1 D1
          C1  
     B1 C1
Il devrait rester :
Code :
1
2
3
4
5
 
A   B   C  D   // Quatre VARIABLES
 
     B1 C1 D1  // Quatre valeurs
A1      C1 D1
Car tout le reste signifie de la perte d'information et la ligne qui contient A1 ( mais pas B1 )
doit etre conservé en vu d'une futur fusion.
Splasher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 18h01   #4
jkofr
Membre éprouvé
 
Avatar de jkofr
 
Homme Jacques Kostic
Senior Consultant DBA (Trivadis SA)
Inscription : octobre 2006
Messages : 369
Détails du profil
Informations personnelles :
Nom : Homme Jacques Kostic
Âge : 44
Localisation : Suisse

Informations professionnelles :
Activité : Senior Consultant DBA (Trivadis SA)
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 369
Points : 482
Points : 482
Envoyer un message via MSN à jkofr
Non, seul la ligne 5 disparait.

jko
__________________
OCP 11g, RAC and Performance & Tuning Expert 11g
RMAN Backup & Recovery, Data Guard and Grid Control
jkofr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2013, 19h11   #5
Splasher
Invité de passage
 
Homme
Étudiant
Inscription : janvier 2013
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2013
Messages : 4
Points : 0
Points : 0
Oui, c'est le cadre des doublons parfait (toute les variables contiennent exactement la meme chose qu'un autre champs).
J'essaye de cibler les doublons en perte d'information ...
Splasher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 11h33   #6
Rams7s
Membre chevronné
 
François
Inscription : février 2010
Messages : 395
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 395
Points : 719
Points : 719
C'est vous qui connaissez les règles, et à moins de les écrire explicitement ici dans un exemple complet, on ne peut rien faire.
Ainsi, dans votre exemple précédent, vous gardez:
De ce que j'ai compris, vous souhaitez à l'étape suivante les fusioner pour obtenir A1 B1 C1 D1
Mais dans le cas suivant, vous faite quoi?
Code :
1
2
3
A1      C1  D1
    B1  C1  D1
    B2  C1  D1
Et pourquoi la solution ne serait-elle pas A1 B3 C1 D1?

Bref, sur quoi vous basez vous pour décider de ce qu'il faut faire ?
Si vous n'avez pas de règle générale, on ne peut pas vous aider, et la solution manuelle de jkofr fonctionne toujours.


Pour revenir à votre problème original:
Vous devriez jeter un oeil du côté des contraintes, UNIQUE ou CHECK afin d'éviter ce problème à l'avenir. Ca va rien résoudre tout de suite, mais ça vous évitera de devoir refaire la même chose dans 6mois.
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 13h16   #7
Rei Ichido
Membre Expert
 
Inscription : août 2009
Messages : 1 013
Détails du profil
Informations forums :
Inscription : août 2009
Messages : 1 013
Points : 1 533
Points : 1 533
Citation:
Envoyé par Rams7s Voir le message
C'est vous qui connaissez les règles, et à moins de les écrire explicitement ici dans un exemple complet, on ne peut rien faire.
Ainsi, dans votre exemple précédent, vous gardez:
De ce que j'ai compris, vous souhaitez à l'étape suivante les fusioner pour obtenir A1 B1 C1 D1
De ce que dit l'OP, il ne s'agit que d'une étape supplémentaire, pour laquelle il ne demande pas (encore) d'aide. Il ne souhaite pour l'instant que traiter les cas où une ligne contient strictement une autre.
Personnellement je ferai chose du genre (j'ai utilisé le rowid faute d'avoir la clé primaire de la table, s'il y en a une) [et c'est non testé/brouillon] :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
WITH tableNb AS
(
SELECT rowid,A,B,C,D
         ,CASE WHEN A IS NOT NULL THEN 1 ELSE 0 END
         +CASE WHEN B IS NOT NULL THEN 1 ELSE 0 END
         +CASE WHEN C IS NOT NULL THEN 1 ELSE 0 END
         +CASE WHEN D IS NOT NULL THEN 1 ELSE 0 END
         AS nb
  FROM TABLE
)
DELETE 
  FROM TABLE t1
 WHERE t1.rowid IN (SELECT t3.rowid
                            FROM tableNb t2, tableNb t3
                          WHERE (t3.A = t2.A OR (t3.A IS NULL AND t2.A IS NOT NULL))
                              AND (t3.B = t2.B OR (t3.B IS NULL AND t2.B IS NOT NULL))
                              AND (t3.C = t2.C OR (t3.C IS NULL AND t2.C IS NOT NULL))
                              AND (t3.D = t2.D OR (t3.D IS NULL AND t2.D IS NOT NULL))
                              AND t3.rowid != t2.rowid  -- ou avec une clé primaire
                              AND (t2.Nb > t3.Nb  -- inclusion stricte
                                     OR
                                     t2.Nb = t3.Nb AND t2.rowid > t3.rowid -- doublon
                                    )
                       )
Rei Ichido est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 15h39   #8
Rams7s
Membre chevronné
 
François
Inscription : février 2010
Messages : 395
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 395
Points : 719
Points : 719
Mais quand il souhaite garder A1 C1 D1 et B1 C1 D1, le second tuple n'est pas contenu dans le premier.

Vrai que j'ai bruler une étape en parlant de la fusion. Il ne faut pas lire cette phrase là! Le reste du message avait justement trait à quelles lignes il faut effacer, et lesquelles garder, et pourquoi.

Enfin, à voir plus tard par Splasher
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2013, 16h23   #9
Splasher
Invité de passage
 
Homme
Étudiant
Inscription : janvier 2013
Messages : 4
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2013
Messages : 4
Points : 0
Points : 0
En fait, pour le traitement de ma base, j'identifie plusieurs étapes de nettoyage :

- Enlever les doublons parfait.
- Enlever les doublons en perte d'information.
- Fusionner les lignes pour prendre le l'information éparpiller.
- Enlever les similaires avec un Algo style levenshtein.

L'étape des doublons parfait est déjà faite.
J'essaye de faire celle des doublons en perte d'information.

Je vais essayer le script de Rei Ichido en l'adaptant a ma base
Splasher est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 07h45.


 
 
 
 
Partenaires

Hébergement Web