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 :

Requête sur plusieurs enregistrements d'une table pour former un résultat


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2007
    Messages : 162
    Points : 94
    Points
    94
    Par défaut Requête sur plusieurs enregistrements d'une table pour former un résultat
    Bonjour,

    Voici la structure de mes 2 tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    TBL_VOITURES
    ID | MARQUE | MODELE
    1  | Pigeot | kangoo 
    2  | Citron | C-Zero 
     
    TBL_CARACT
    ID_VOIT | NOM_CARACT | VALEUR
    1       | couleur    | rouge
    1       | poids      | 950
    1       | vMax       | 140
    2       | couleur    | bleue
    2       | vMax       | 120
    Mon but est d'écrire une requête me retournant une liste d'enregistrements telle que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ID | MARQUE | MODELE  | couleur | poids | vitesse
    1  | Pigeot | kangoo  | rouge   | 950   | 140 
    2  | Citron | C-Zero  | bleue   |       | 120
    J'attire votre attentsion sur le fait que tous les enregistrements n'ont pas toutes les valeurs (par ex. : ID 2 n'a pas de poids).

    J'ai essayé d'écrire une requete avec des jointures (une par caractéristique) mais cela me parait bien compliqué.

    Toute aide serai bienvenue.
    Cédric

  2. #2
    Membre habitué Avatar de Joel Pinto Ribeiro
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 95
    Points : 145
    Points
    145
    Par défaut
    Et si tu modifiais ta table TBL_CARACT
    de sorte à ce qu'elle ressemble plutot à cela :

    ID_VOIT | couleur| poids | vMax
    1 | rouge |950 |140
    2 | bleu |Null | 120


    ça simplifierait ta problematique.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2007
    Messages : 162
    Points : 94
    Points
    94
    Par défaut
    Hello,

    Merci mais je ne veux / peux pas changer la structure de la table. Déjà parce que c'est une appli existante et surtout que la liste des options n'est pas fixe.

    Cedric

  4. #4
    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,

    Si votre groupe d'option n'est pas fixe, alors vous aurez à maintenir la requête à chaque ajout / suppression de caractéristiques.

    Bref, ca sera crade dans tous les cas.

    Il faut gérer ca côté applicatif.

    Vous pourriez, cependant, vous faciliter la vie en utilisant la fonction group_concat de MySql afin de prémacher le travail en générant une map / liste .

    Vous auriez en sorti, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    id    marque   modele   attribut
    ------------------------------------
    1    Renault    Kangoo  (couleur:rouge;vitesse:240)
    .....

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Il faut traiter la présentation des données côté applicatif.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Points : 1 631
    Points
    1 631
    Par défaut
    Bonjour,

    la requête pour faire apparaître les différentes caractéristiques en une seul requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT tv.id, tv.marque, tv.model, GROUP_CONCAT(CONCAT(nomcarac, ':', valeur)) carac
    FROM tv
    INNER JOIN tc ON tv.id = tc.id_voit
    GROUP BY id;

    cette requête te donne comme résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    +------+--------+--------+----------------------------------+
    | id   | marque | model  | carac                            |
    +------+--------+--------+----------------------------------+
    |    1 | Pigeot | kangoo | vMax:140,couleur:rouge,poids:950 |
    |    2 | Citron | C-Zero | vMax:120,couleur:bleue           |
    +------+--------+--------+----------------------------------+
    Maintenant ce code la n'est pas très "propre" car tu devra quand même traiter le résultat, le mettre en forme dans différents tableaux pour pouvoir ensuite exploiter ces données donc autant le faire directement en traitant ta requête,

    donc j'aurais tendance a plûtot partir sur une requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT tv.id, tv.marque, tv.model, tc.nomcarac, tc.valeur
    FROM tv
    INNER JOIN tc ON id = id_voit;

    qui te donne comme résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    +------+--------+--------+----------+--------+
    | id   | marque | model  | nomcarac | valeur |
    +------+--------+--------+----------+--------+
    |    1 | Pigeot | kangoo | couleur  | rouge  |
    |    1 | Pigeot | kangoo | poids    | 950    |
    |    1 | Pigeot | kangoo | vMax     | 140    |
    |    2 | Citron | C-Zero | couleur  | bleue  |
    |    2 | Citron | C-Zero | vMax     | 120    |
    +------+--------+--------+----------+--------+
    ensuite on prend par exemple en langage PHP le traitement de cette requête :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //$requete->fetch() te renvoi un tableau avec les différentes colonnes de ta requête et l assigne à $resultat
    while($resultat = $requete->fetch() ){
        //Donc pour chaque ligne retournée par la requête on créer un tableau qui va regrouper les caractéristiques d une voiture
        $voitures[$resultat['id']] = array('marque' => $resultat['marque'],
                                           'model' =>$resultat['model'])
     
        //Chaque ligne de la requête renseigne sur une nouvelle caractéristique
        //On ajoute alors un nouveau tableau à liste_carac de la voiture concerné avec le nom de la caractéristique et sa valeur
        $voitures[$resultat['id']]['liste_carac'][] = array('nom' => $resultat['nomcarac'],
                                                            'valeur' => $resultat['valeur'] )
     
        ) 
    }

    Au final tu te retourvera avec un tableau comme celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    array(
        [1]=> array('marque'=>'Pigeot',
                     'model'=>'kangoo',
                     'liste_carac'=>array([0] => array('nom'=>'couleur',
                                                   'valeur'=>'rouge'),
                                          [1] => array('nom'=>'poids',
                                                       'valeur'=>'950') )
         ), ...
        //Ainsi de suite pour chaque voiture présente dans ta BDD
    )
    Tu peux même simplifer le tableau liste_carac pour avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0] => array('couleur' => 'rouge')
    Il faudra que la partie traitement du tableau liste_carac ressemble à :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $voitures[$resultat['id']]['liste_carac'][] = array($resultat['nomcarac'] => $resultat['valeur'] )

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2007
    Messages : 162
    Points : 94
    Points
    94
    Par défaut
    Merci, la solution du GROUP_CONCAT parait vraiment bien, je vais me pencher dessus.

    Voici la solution que j'utilisais, mais sur certains serveur apparemment cela ne fonctionne pas, et je ne sais pas pourquoi, d’où ma question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT V.*, C1.valeur AS couleur, C2.valeur AS vitesse, C3.valeur AS poids
    FROM TBL_VOITURE AS V
    LEFT JOIN TBL_CARACT C1 ON (C1.id_voit = V.id AND C1.CARACT='couleur')
    LEFT JOIN TBL_CARACT C2 ON (C2.id_voit = V.id AND C2.CARACT='vitesse')
    LEFT JOIN TBL_CARACT C3 ON (C3.id_voit = V.id AND C3.CARACT='poids')
    Ce qui me retourne le résultat présenté dans mon premier post, mais est-ce bon niveau perf? Et je soupçonne que ce ne soit pas terrible comme algo.

    Merci de jeter un œil.

    Cédric

  8. #8
    Membre expérimenté
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Points : 1 631
    Points
    1 631
    Par défaut
    Ta solution n'est pas vraiment pratique car tu va devoir ajouter une nouvelle jointure externe pour chaque nouvelle caractéristique alors que mes deux méthodes ne tiennent pas compte du nombre de caractéristiques disponible dans la bdd.

    Tu peux remplacer la jointure interne par une jointure externe sur les deux requêtes, comme ça la valeur de carac sera null si la voiture n'a aucune caractéristique renseignée.

    De plus, la solution avec le group concat n'est vraiment pas conseillée, ce n'est pas parce qu'une requête ne retourne qu'une seul ligne par voiture qu'elle sera plus performante et plus simple à traiter côté applicatif. C'est même le contraire !

Discussions similaires

  1. [AC-2003] lancer une requête sur plusieurs enregistrement
    Par yieiyiei dans le forum VBA Access
    Réponses: 8
    Dernier message: 21/03/2015, 11h08
  2. Réponses: 5
    Dernier message: 27/03/2013, 15h29
  3. [HTML] mettre un DIV sur plusieurs champs d'une table
    Par Nixar dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 07/09/2007, 15h13
  4. Réponses: 4
    Dernier message: 22/03/2007, 18h28
  5. [WD9] Cliquer sur des enregistrements dans une table
    Par oz80 dans le forum WinDev
    Réponses: 2
    Dernier message: 15/12/2005, 20h11

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