IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Remplacer plusieurs enregistrements par un seul:conditionnel


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut Remplacer plusieurs enregistrements par un seul:conditionnel
    Bonjour à tous,
    J'ai une table qui possède 6 champs(A, B, C, D, E et F), le champ B est la clé. Pour mieux illustrer mon problème, je donne des enregistrements dans ce qui suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    SAR-T	7701		102	05	07	X3			
    SAR-T	7702		102	05	07	X3			
    SAR-T	7703		102	05	07	X3			
    SAR-T	7704		102	05	07	X3			
    SAR-T 	7705		102	05	07	X3			
    SAR-T	7706		102	05	07	X3			
    SAR-T	7707		102	05	07	X3			
    SAR-T	7708		102	05	07	X3			
    SAR-T	7709		102	05	07	X3			
    SAR-T	7710		102	05	07	X3			
    SAR-T	7712		102	05	07	X3			
    SAR-T	7713		102	05	07	X3			
    SAR-T	7714		102	05	07	X3			
    SAR-T	7715		102	05	07	X3			
    SAR-T	7716		102	05	07	X3			
    SAR-T	7717		102	05	07	X3			
    SAR-T	7718		102	05	07	X3			
    SAR-T	7719		102	05	07	X3			
    SAR-T	7724		102	05	07	X3			
    SAR-T	7725		102	05	07	X3			
    GAR-Z	7726		052	035	076	X3			
    SAR-T	7728		102	05	07	X3			
    SAR-T	7729		102	05	07	X3			
    SAR-T	7731		102	05	07	X3			
    SAR-T	7734		102	05	07	X3			
    GAR-Z	7736		052	99	076	X3			
    SAR-T	7739		102	05	07	X3			
    SAR-T	7740		102	05	07	X3
    Je voudrais regrouper les enregistrements qui sont identiques sauf par leurs champs B(qui se suivent) par un seul représentant
    Exemple remplacer les 10 premiers enregistrements(qui ont des champs B consécutifs de 7701 à 7709 par un seul) par celui ci
    SAR-T 770 102 05 07 X3
    Notez que le champ B ne comporte désormais que 3 chiffres(et que le fait qu'il soit une clé ne gêne pas car on est assuré qu'il n'y a pas d'autre 770

    Il en sera de même pour les enregistrements de 7710 à 7719 qui seront remplacés par l'enregistrement
    SAR-T 771 102 05 07 X3

    et ainsi de suite. Si j'avais un seul champ qui diffère dans les 10 le regroupement serait impossible; donc ce regroupement est conditionnel.

    Je suis sous MySQL
    Merci infiniment de votre réponse

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 161
    Points : 75
    Points
    75
    Par défaut
    Si j'ai bien compris, ceci est une simple requête de doublons.
    Sauf qu'il faut les regrouper par ID par dizaine.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
     
    CREATE TABLE TABLE1
    	([NAME] varchar(5), [ID] INTEGER,
        [ID2] varchar(5), [ID3] varchar(5),
         [ID4] varchar(5),[ID5] varchar(5))
    ;
     
    INSERT INTO Table1
    	([NAME], [ID], [ID2], [ID3], [ID4], [ID5])
    VALUES
    ('SAR-T',	'7701', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7702', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7703', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7704', '102',	'05',	'07', 'X3'),
    ('SAR-T',   '7705', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7706', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7707', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7708', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7709', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7710', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7712', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7713', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7714', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7715', '102',	'05',	'07', 'X3'),
    ('GAR-Z',	'7726', '052',	'035',	'076', 'X3'),
    ('SAR-T',	'7717', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7718', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7719', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7724', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7725', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7728', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7729', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7731', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7734', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7739', '102',	'05',	'07', 'X3');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT t1.name,  t1.ID / 10 AS ID
    FROM TABLE1 t1
    GROUP BY t1.ID / 10, t1.name
    HAVING Count(*) > 1
    ce qui donne :

    NAME ID
    SAR-T 770
    SAR-T 771
    SAR-T 772
    SAR-T 773
    Il te suffit de regrouper tous les données que tu veux récupérer pour les afficher.

    Le problème que tu auras c'est que lorsque qu'il y aura plusieurs données identiques dans chaque dizaine ta clé ID ne sera plus primaire.

    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ('SAR-T',	'7701', '102',	'05',	'07', 'X3'),
    ('SAR-T',	'7702', '102',	'05',	'07', 'X3'),
    ('SAR-Z',	'7703', '102',	'06',	'08', 'X3'),
    ('SAR-Z',	'7704', '102',	'06',	'08', 'X3'),
    Cela donnera :
    NAME ID
    SAR-T 770
    SAR-Z 770

  3. #3
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Merci xoum89 de cette réponse qui me fait tout de suite comprendre que je n'ai pas bien posé mon problème. L'idée des dizaines y est , mais avec une nuance !

    Je vais l'exposer d'une autre manière en faisant un petit changement dans les données:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    SAR-T	270		102	05	07	X3
    SAR-T	271		102	05	07	X3
    SAR-T	272		102	05	07	X3
    SAR-T	273		102	05	07	X3						
    SAR-T	274		102	05	07	X3			
    SAR-T	275		102	05	07	X3
    SAR-T	276		102	05	07	X3
    SAR-T	277		102	05	07	X3			
    SAR-T	278		102	05	07	X3
    SAR-T	279		102	05	07	X3	
    SAR-T	7701		102	05	07	X3			
    SAR-T	7702		102	05	07	X3			
    SAR-T	7703		102	05	07	X3			
    SAR-T	7704		102	05	07	X3					
    SAR-T	7706		102	05	07	X3			
    SAR-T	7707		102	05	07	X3					
    SAR-T	7709		102	05	07	X3			
    SAR-T	7710		102	05	07	X3			
    SAR-T	7712		102	05	07	X3			
    SAR-T	7713		102	05	07	X3			
    SAR-T	7714		102	05	07	X3			
    SAR-T	7715		102	05	07	X3			
    SAR-T	7716		102	05	07	X3			
    SAR-T	7717		102	05	07	X3			
    SAR-T	7718		102	05	07	X3			
    SAR-T	7719		102	05	07	X3
    SAR-T	7720		102	05	07	X3			
    SAR-T	7721		102	05	07	X3
    SAR-T	7722		102	05	07	X3			
    SAR-T	7723		102	05	07	X3			
    SAR-T	7724		102	05	07	X3			
    SAR-T	7725		102	05	07	X3			
    GAR-Z	7726		052	035	076	X3			
    SAR-T	7727		102	05	07	X3			
    SAR-T	7728		102	05	07	X3
    SAR-T	7729		102	05	07	X3						
    SAR-T	7740		102	05	07	X3
    SAR-T	7739		102	05	07	X3
    de la ligne 1 à la ligne 10, on supprime tout en remplaçant par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SAR-T	27		102	05	07	X3
    de la ligne 11 à la ligne 17
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SAR-T	770		102	05	07	X3
    malgré le fait que la lignes correspondant aux deux IDs 7705 et 7708 n'existent pas dans la liste.
    de la ligne 18 à 26, on supprime tout pour remplacer par la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SAR-T	771		102	05	07	X3
    de la ligne 27 à 37 on garde tout tel quel car malgré la sériation parfaite de l'ID, on a des valeur différentes des champs C, D et E à la ligne 33, donc on ne peut pas grouper.


    Merci infiniment d'avoir la patience de me lire car je trouve tout ça ennuyeux

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 161
    Points : 75
    Points
    75
    Par défaut
    Donc au lieu d'avoir un Il suffit juste de prendre que ce qui sont exactement pareil.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT t1.name,  t1.ID / 10 AS ID
    FROM TABLE1 t1
    GROUP BY t1.ID / 10, t1.name
    HAVING Count(1) in (SELECT count(1)
    FROM TABLE1 t1
    GROUP BY t1.ID/10)
    La première requête vas te retourner le nombre d’occurrences qui sont pareil (avec tous les champs)
    La second va te retourner le nombre d’occurrences dans tes dizaines.
    Si le chiffre n'est pas le même alors on ne prend pas.

    Puis il faudra refaire une requête (sur celle la) pour remettre les occurrences qui n'ont pas été mise.

    Résultat :
    SAR-T 770
    SAR-T 771
    SAR-T 773
    Le 772 n'est pas pris en compte

    Et pour lier ce qui n'ont pas été pris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT case when req.ID IS NULL then t1.ID else req.ID end as ID
    FROM TABLE1 t1
    LEFT OUTER JOIN
    (
    SELECT t1.name,  t1.ID / 10 AS ID
    FROM TABLE1 t1
    GROUP BY t1.ID / 10, t1.name
    HAVING Count(1) IN (SELECT count(1)
    FROM TABLE1 t1
    GROUP BY t1.ID/10)
     ) req
    ON t1.ID /10 = req.ID
    A toi de rajouter les champs voulu après.

  5. #5
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    ReBonjour xoum89;
    Encore une fois mille Merci,
    Permets moi de t'importuner encore une fois par ces 3 questions:

    1. Est ce que la requête permet d'avoir le 27 (en principe oui par ce que /10 passe par là!) ;juste parce que je n'ai pas vu 27 dans la liste
    SAR-T 770
    SAR-T 771
    SAR-T 773
    2. Vous utilisez combien de tables car je vois Table1 t1 et req (ou alors req serait une variable tout simplement?

    3. pas de question tout le reste est clair et limpide

  6. #6
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour,

    J'ai essayé la requête suivante pour 10.000 enregistrements seulement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT Table1.nomination,  Table1.id / 10 FROM  Table1 GROUP BY Table1.id / 10, Table1.nomination HAVING Count(1) IN (SELECT count(1)
    FROM Table1 GROUP BY Table1.id/10)
    Et c'est extrêmement lent!

    Merci d'avance de votre aide

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 161
    Points : 75
    Points
    75
    Par défaut
    Salut et bonne année.

    1. Est ce que la requête permet d'avoir le 27 (en principe oui par ce que /10 passe par là!) ;juste parce que je n'ai pas vu 27 dans la liste
    Oui cela fonctionnera sur tout (Mais il y aura surement un bug sur les chiffres)

    Vous utilisez combien de tables car je vois Table1 t1 et req (ou alors req serait une variable tout simplement?
    Je n'utilise que une seul table. Mais je fais deux requêtes imbriquées.
    La première me permet de regrouper les lignes qui sont exactement pareil.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT t1.name,  t1.ID / 10 AS ID
    FROM TABLE1 t1
    GROUP BY t1.ID / 10, t1.name
    Ca regroupera par ID/10 puis par nom et ainsi de suite si tu rajoutes des conditions.
    La seconde requêtes te permets de savoir le nombre d’occurrence regroupées par ID/10.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT count(1)
    FROM TABLE1 t1
    GROUP BY t1.ID/10
    En liant les deux cela te permets de savoir si les ID regrouper dans les deux on le même nombres d'occurrences.
    La requête possède un IN et des CASES forcement cela sera plus long qu'une simple requête mais cela me semble bizarre que ça soit extrêmement lent.

    Pour faire un INSERT sur cette requête il te faut bien remettre dans ton SELECT les mêmes champs que dans ta table.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Il me semble apercevoir un problème potentiel: la sous-requête qui compte le nombre d'occurrences pad id/10 n'est pas corrélée.
    Donc dans l'exemple donnée, pour les lignes 28 à 37, exception faite de la 34, vont être regroupée.
    En effet, si on les regroupe, on a 9 lignes.
    Or la sous-requête renvoie entre autre la valeur 9 (du fait des lignes 12 à 19).

    Me trompe-je ?

    Tatayo.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 161
    Points : 75
    Points
    75
    Par défaut
    @tatayo : tu as complètement raison heureusement que tu passes part la .

    Le IN vas regrouper un ensemble de valeur (qui statistiquement va contenir tout les chiffres de 1 à 9)

    Bon avec cette requete tu auras bien toutes les bonnes liaisons.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT *
    FROM
    (
    SELECT t1.name,  t1.ID / 10 AS ID, count(1) nb
    FROM TABLE1 t1
    GROUP BY t1.ID / 10, t1.name
    ) req1
    JOIN (SELECT t1.ID/10 AS ID, count(1) AS nb
    FROM TABLE1 t1
    GROUP BY t1.ID/10) req2
    ON req2.ID = req1.ID
    WHERE req2.nb = req1.nb
    Oublie pas de rajouter dans ton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GROUP BY t1.ID / 10, t1.name
    tes colonnes
    A, B, C, D, E et F

  10. #10
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    perso j'attaquerai ce probleme en 2 requetes.

    La 1ere qui recense les "doublons parfait"
    La 2eme qui recense le reste.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select max(a), b/10, max(c), max(d), max(e), max(f)
    from tmp
    group by b/10
    having count( distinct a) = 1 and count(distinct c) =1 and count(distinct d) = 1 and count(distinct e)=1 and count(distinct f) = 1
    union all
    select a, b/10, c, d, e, f from tmp a
    where exists (select 1 from tmp b where a.b/10 = b.b/10 and (a.a <> b.a or a.c <> b.c or a.e <> b.e or a.f <> b.f))
    Ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    "SAR-T";27;102;5;7;"X3"
    "SAR-T";770;102;5;7;"X3"
    "SAR-T";771;102;5;7;"X3"
    "SAR-T";773;102;5;7;"X3"
    "SAR-T";774;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "GAR-Z";772;52;35;76;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    "SAR-T";772;102;5;7;"X3"
    Concernant les perfs, c'est juste impossible.
    Scannage de table obligatoire vu la demande.

  11. #11
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour xoum89, bonjour à tous une bonne et heureuse année 2014,

    En essayant d'appliquer les requêtes j'ai mis Floor(ID/10) pour éviter les virgules. Mais je crois qu'il faudrait introduire le SELECT CASE suggéré par xoum89, car je constate que des lignes qui ne sont pas concernées ont eu leur ID transformé en Floor(ID/10) ce qui ne doit pas être. Je vous rappelle que le regroupement ne concerne que les enregistrements qui:
    • sont identiques par tous leurs champs sauf le clé en B (qui est une valeur entière)
    • ont leur champ clé qui appartient à une sériation existante dans dans d'autres enregistrements(exple :58, dans une série 52,53,54,56,57,59 et qui en plus partagent en toute rigueur tous les autres champs vont être remplacé par un seul enregistrement ayant pour ID 5 !).

    Pour mieux illustrer un exemple des cinq enregistrements qui suivent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Zarbi 235  192 05 07 R3 
    Zarbi 236  192 05 07 R9 
    Zarbi 237  196 16 07 R3 
    Zarbi 238  192 05 07 R3 
    Darbi 239  192 05 07 R3
    Les 2 enregistrements
    Zarbi 235 192 05 07 R3 et Zarbi 238 192 05 07 R3 seront regroupés en Zarbi 23 192 05 07 R3
    les 3 autres seront laissés tels qu'ils sont
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Zarbi 236  192 05 07 R9 
    Zarbi 237  196 16 07 R3 
    Darbi 239  192 05 07 R3
    donc au final on aurait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Zarbi 23  192 05 07 R3 
    Zarbi 236  192 05 07 R9 
    Zarbi 237  196 16 07 R3 
    Darbi 239  192 05 07 R3

    Enfin comme plusieurs requêtes et jointures seraient nécessaires avec des CASE ou des IF, est ce que quelqu'un pourrait indiquer tout le cheminement.

    Ah j'allais oublier de dire que l'unicité du nouvel ID ainsi crée est garantie donc aucun risque de conflit de clé possible!

    Merci infiniment.

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Donc le regroupement peut se voir ainsi:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    select distinct Floor(t1.ID/10),t1.col2,t1.col3,t1.col4
    from LaTable as t1
    inner join LaTable as t2 on Floor(t1.ID/10) = Floor(t2.ID/10) and t1.col1 = t2.col1 and t1.col2 = t2.col2 and t1.col3 = t2.col3 and t1.col4 = t2.col4 and t1.id <> t2.id
    union
    select t1.ID,t1.col2,t1.col3,t1.col4
    from LaTable as t1
    left outer join LaTable as t2 on Floor(t1.ID/10) = Floor(t2.ID/10) and t1.col1 = t2.col1 and t1.col2 = t2.col2 and t1.col3 = t2.col3 and t1.col4 = t2.col4 and t1.id <> t2.id
    where t2.id is null
    La première partie de la requête récupère les lignes pour lesquelles il en existe un autre avec l'Id dans la même dizaine (mais différent), et les autres colonnes qui correspondent.
    La deuxième partie prend les autres lignes.

    Tatayo.

  13. #13
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Merci beaucoup Tatayo, merci à tous,

    J'ai appliqué la requête et j'avoue que j'utilisé pour ça un truc graphique et peu professionnel et qui après près d'une heure de temps il me sort:
    Fatal error: Maximum execution time of 300 seconds exceeded in C:\Program Files\EasyPHP-5.3.3.1\phpmyadmin\libraries\dbi\mysql.dbi.lib.php on line 176
    .

    Je suis donc allé en mode commande et j'essaie de récupérer la sortie dans un tableau de même structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mysql>insert into ttest SELECT DISTINCT t1.name,Floor(t1.ID/10),t1.col2, etc..
    et ça fait une bonne demi heure. J'espère que ça ira.

    Merci infiniment

  14. #14
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour Tatayo, bonjour à tous,
    ça donne du résultat mais trouve des doublons dans les id qui ne devraient pas être regroupés (donc ne devraient pas être divisés par 10: j'ai fait les vérifications).
    Je remarque aussi que le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT Floor(t1.ID/10),t1.col2,t1.col3,t1.col4 FROM LATABLE as t1
    divise inconditionnellement id par 10.

    Autre question est ce qu'on ne doit pas créer plusieurs tables supplémentaires(3 ou 4) et les remplir tour à tour par les résultats des requêtes unitaires, au lieu de cascader les requêtes: histoire d'y voir plus clair, surtout pour moi qui ne suis pas très doué en SQL

    Merci d'avance.

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Peut-on avoir un exemple de lignes qui sont regroupées à tord ?

    Tatayo.

  16. #16
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour,
    Je vous envoie l'export csv de la table avec ";" comme séparateur.

    elle contient 5 champs:
    • un intitulé pays
    • un préfixe(indicatif pays + éventuellement un suffixe en plus) c'est cela le champ B(clé) dont je vous ai parlé et sur la base duquel les regroupements seront faits à la base de ce préfixe.
    • Trois champs représentant 3 valeurs réelles.


    pour l'ID ou prefixe dédoublé(après division par 10) est le 138!

    si je prend l'exemple de la France(indicatif 33) et que je considère les enregistrements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    France - Mobile Others	3365660	99	0.0342	99
    France - Mobile Others	3365661	99	0.0342	99
    France - Mobile Others	3365662	99	0.0342	99
    France - Mobile Others	3365663	99	0.0342	99
    France - Mobile Others	3365664	99	0.0342	99
    France - Mobile Others	3365665	99	0.0342	99
    France - Mobile SFR	3365666	99	0.0175	99
    France - Mobile SFR	3365667	99	0.0175	99
    France - Mobile SFR	3365668	99	0.0175	99
    France - Mobile SFR	3365669	99	0.0175	99
    ne peut pas être regroupé car 0.0342 est différent de 0.0175


    A l'inverse des 8 enregistrements qui suivent où on peut regrouper
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    France - Fixed ILIAD	3398031	99	99	0.01
    France - Fixed ILIAD	3398032	99	99	0.01
    France - Fixed ILIAD	3398033	99	99	0.01
    France - Fixed ILIAD	3398034	99	99	0.01
    France - Fixed ILIAD	3398036	99	99	0.01
    France - Fixed ILIAD	3398037	99	99	0.01
    France - Fixed ILIAD	3398038	99	99	0.01
    France - Fixed ILIAD	3398039	99	99	0.01
    et cet enregistrement représentera les 8 précédents qui seront tout simplement supprimés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    France - Fixed ILIAD	339803	99	99	0.01
    Merci infiniment
    Fichiers attachés Fichiers attachés

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Citation Envoyé par maestro1303 Voir le message
    pour l'ID ou prefixe dédoublé(après division par 10) est le 138!
    Je ne comprends pas bien d'où sort ce 138 ...
    Quoi qu'il en soit il faut donc regrouper 2 lignes si:
    1. L'Id / 10 des deux lignes sont égaux
    2. Toutes les autres colonnes sont égales
    3. Il n'existe pas d'autre ligne pour lesquelles
    a. L'Id / 10 des deux lignes sont égaux
    b. les autres colonnes sont l'intitulé sont égales
    c. l'intitulé est différent

    Et les lignes restent "telle quelle" si il existe au moins une ligne pour laquelle l'ID / 10 = l'ID / 10 de la ligne considéré et au moins une des autres colonne diffère.

    Je laisse coder le tout en SQL

    Pour ce qui est de la performance, je pense qu'il faudrait ajouter une colonne pour y stocker l'id/10, et de définir un index avec doublon dessus. Cela permettrai de faire des jointure sur une colonne indexée sans passer par une fonction (qui rend l'index inutilisable).

    Tatayo

  18. #18
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour Tatayo et mille merci,
    C'est bien celà sauf que je n'ai pas bien compris le b et le c du 3. Surtout ce que vous voulez dire par intitulé. Pourriez vous revoir les phrases en b et en a. Merci

    Je vous ai envoyé un fichier de 10.000 enregistrements et pour la redondance de clé 138 c'est en appliquant la requête d'hier à cette table qu'on l'obtient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT t1.name,Floor(t1.ID/10),t1.col2, etc..
    .




    Merci d'avance.

  19. #19
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    bonsoir,
    Je viens de créer un champ dixi dans lequel je mets l'ID amputé du dernier chiffre de droite. J'ai désormais les champ
    A, dixi, B,C,D,E
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT  A, dixi, B,C,D,E, count(*)
    FROM `PARPAYS`
    GROUP BY concat( dixi, C,D,E )
    Les lignes ayant un seul représentant sont "groupables"(dixi unique). Celles avec plus d'une entrée ne le sont pas et il faudrait y revenir en détail...
    On met cette sortie dans un autre tableau qu’on parcourt :si on rencontre une seule entrée du champ dixi on supprime tous ses représentants dans la table PARPAYS et on les remplace par cette unique ligne ; le reste on touche pas.

    Voilà ceci n’est pas très élégant mais ça tire d’affaire(Merci Tatayo) . Seulement ce n’est pas fini parce qu’il faudra après s’attaquer aux centaines pour les regrouper de la même manière etc…

    Est-ce qu’une âme charitable aurait une meilleure solution ?

    En tout cas Merci à tous et à Tatayo qui est derrière l’idée du champ DIXIème

  20. #20
    Membre régulier
    Inscrit en
    Juillet 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Juillet 2006
    Messages : 232
    Points : 79
    Points
    79
    Par défaut
    Bonjour à tous,
    Aec l'apport et les suggestions de tous mon problème est finalement résolu: j'ai donc crée plusieurs tableaux supplémentaire, rajouté des champs auto_increment car je devais triturer continuellement le champ ID le diviser par 10 pour regrouper et le remplacer par l'ID etc...Bref on peut dire que grâce à vos aides j'ai pu enfin voir le bout du tunnel et l'essentiel est reglé.

    Je marque donc le sujet en résolu,
    Merci infiniment.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [String] remplacer plusieurs espaces par un seul
    Par scraly dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 01/12/2010, 15h25
  2. [AC-2003] Remplacer plusieurs textbox par un label et une seule textbox
    Par buzz73 dans le forum IHM
    Réponses: 2
    Dernier message: 21/12/2009, 12h35
  3. Remplacement de plusieurs espaces par une seul
    Par Bayard dans le forum Général Python
    Réponses: 2
    Dernier message: 23/11/2008, 18h10
  4. Remplacer plusieurs espace par un seul
    Par rjcab dans le forum VBA Access
    Réponses: 14
    Dernier message: 04/07/2008, 12h28
  5. remplacer plusieurs mots par un seul mot
    Par nivose110 dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 07/02/2007, 09h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo