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

Requêtes MySQL Discussion :

Je bute sur une requête qui est, a priori, simple.


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut Je bute sur une requête qui est, a priori, simple.
    Bonjour à tous,

    Mon niveau en SQL est moyen. Je suis confronté à un problème que je ne sais pas par quel bout prendre.

    Je dispose d'une table qui contient deux champs : Les champs "CLeft" et "CRight".

    Je cherche à regrouper les lignes de la table suivant un critère qui porte sur ces deux champs.

    Pour décrire le critère, je vais exposer un exemple (ce sera plus simple) :

    Exemple de table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    id CLeft CRight
    1  11    12
    2  11    12
    3  11    12
    4  12    11
    5  12    11
    6  22    23
    7  22    23
    8  23    22
    9  11    46
    Ce jeu de valeurs génère trois groupes :
    • Le premier groupe contient les 5 lignes désignées par id=1,2,3,4,5.
    • Le deuxième groupe contient les 3 lignes désignées par id=6,7,8.
    • Le troisième groupe ciontient la ligne désignée par id=9.


    Mon point de vue de développeur m'incite à écrire un scripte qui mélangera du code et du SQL. Cette solution n'est ni simple, ni performante.

    Je pense qu'il existe une solution "100% SQL"... Éventuellement on pourrait créer des tables temporaires, et décomposer le traitement en plusieurs requêtes.

    Je précise que j'utilise MySql.

    Avez-vous des suggestions pour rendre ce traitement performant?

    Merci à tous,

    Denis

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Peut-être quelque chose comme ça, mais ça ne fonctionnera qu'avec deux colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      SELECT LEAST(CLeft, CRight)    as Borne1,
             GREATEST(CLeft, CRight) as Borne2,
             GROUP_CONCAT(id ORDER BY id ASC SEPARATOR ',') as Groupe
        FROM MaTable
    GROUP BY LEAST(CLeft, CRight),
             GREATEST(CLeft, CRight);

  3. #3
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Peut-être quelque chose comme ça, mais ça ne fonctionnera qu'avec deux colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      SELECT LEAST(CLeft, CRight)    as Borne1,
             GREATEST(CLeft, CRight) as Borne2,
             GROUP_CONCAT(id ORDER BY id ASC SEPARATOR ',') as Groupe
        FROM MaTable
    GROUP BY LEAST(CLeft, CRight),
             GREATEST(CLeft, CRight);
    Merci Waldar,

    Je n'aurais jamais pensé à cette solution!

    J'ai décortiqué la requête pour la comprendre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE  TABLE IF NOT EXISTS `ex` (
      `idex` INT NOT NULL AUTO_INCREMENT ,
      `CLeft` INT NULL ,
      `CRight` INT NULL ,
      PRIMARY KEY (`idex`) )
    ENGINE = InnoDB;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    mysql> insert into ex set CLeft=11, CRight=22;
    mysql> insert into ex set CLeft=11, CRight=22;
    mysql> insert into ex set CLeft=11, CRight=22;
    mysql> insert into ex set CLeft=22, CRight=11;
    mysql> insert into ex set CLeft=22, CRight=11;
    mysql> insert into ex set CLeft=15, CRight=20;
    mysql> insert into ex set CLeft=15, CRight=20;
    mysql> insert into ex set CLeft=15, CRight=20;
    mysql> insert into ex set CLeft=20, CRight=15;
    mysql> insert into ex set CLeft=15, CRight=16;
    mysql> insert into ex set CLeft=15, CRight=16;
    mysql> insert into ex set CLeft=15, CRight=16;
    mysql> insert into ex set CLeft=16, CRight=15;
    mysql> insert into ex set CLeft=11, CRight=12;
    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
    mysql> select * from ex;
    +------+-------+--------+
    | idex | CLeft | CRight |
    +------+-------+--------+
    |    1 |    11 |     22 |
    |    2 |    11 |     22 |
    |    3 |    11 |     22 |
    |    4 |    22 |     11 |
    |    5 |    22 |     11 |
    |    6 |    15 |     20 |
    |    7 |    15 |     20 |
    |    8 |    15 |     20 |
    |    9 |    20 |     15 |
    |   10 |    15 |     16 |
    |   11 |    15 |     16 |
    |   12 |    15 |     16 |
    |   13 |    16 |     15 |
    |   14 |    11 |     12 |
    +------+-------+--------+
    14 rows in set (0.00 sec)
    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
     
    mysql> SELECT LEAST(CLeft, CRight) as Borne1,
        ->          GREATEST(CLeft, CRight) as Borne2,
        ->          GROUP_CONCAT(idex ORDER BY idex ASC SEPARATOR ',') as Groupe
        ->     FROM ex
        -> GROUP BY LEAST(CLeft, CRight),
        ->          GREATEST(CLeft, CRight);
    +--------+--------+-------------+
    | Borne1 | Borne2 | Groupe      |
    +--------+--------+-------------+
    |     11 |     12 | 14          |
    |     11 |     22 | 1,2,3,4,5   |
    |     15 |     16 | 10,11,12,13 |
    |     15 |     20 | 6,7,8,9     |
    +--------+--------+-------------+
    4 rows in set (0.00 sec)

    Ça marche! Merci! Vraiment, c'est génial!

    A+

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

Discussions similaires

  1. [PDO] General error: 2031 sur une requête qui marche avec PHPMyAdmin
    Par laurentSc dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 14/12/2015, 13h17
  2. [Python 3.X] Besoin urgent d'aide sur une fonction qui me semble pourtant simple à créer.
    Par Mrflop124 dans le forum Général Python
    Réponses: 7
    Dernier message: 25/04/2015, 17h13
  3. Réponses: 10
    Dernier message: 18/05/2011, 14h56
  4. sqlite3, message d'erreur sur une requête qui fonctionne
    Par stefh7 dans le forum Général Python
    Réponses: 13
    Dernier message: 25/02/2011, 13h48
  5. Réponses: 2
    Dernier message: 21/10/2008, 13h57

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