Partage
  • Partager sur Facebook
  • Partager sur Twitter

Requête SQL incontrolable

Elle ne m'obéit pas...

Sujet résolu
    15 novembre 2010 à 21:07:42

    Bonsoir !

    Je me suis déjà exprimé dans un précédent post(si possible le supprimer) et je l'ai fait de manière très maladroite.
    Voilà une meilleure présentation de mon problème :
    J'ai 3 tables :
    - Membres (les membres du site)
    Image utilisateur

    - Categories (les categories des membres : developpeur, designer etc..)
    Image utilisateur

    - Compétences (les compétences des membres dans chaque categorie (php/mysql dans developpeur, 2D et 3D dans designer etc...)
    Image utilisateur


    Mon objectif est le suivant : (dans le cadre d'une recherche par competence, categorie etc...)
    Afficher pour chaque membre qui repond au critère de recherche son pseudo, ses compétences, sa date de postulation etc...
    Le problème survient à ce moment de la reflexion, j'ai joint les 3 tables dans ma requête SQL mais le script n'effectue pas ce que je voudrais faire !


    SELECT co.competence, co.type, co.temps, co.note, co.id, ca.dispo as dispo, ca.refs, m.pseudo, ca.id AS idcategorie,
    ca.categorie, DATE_FORMAT(datepostulation, "%d/%m/%Y") AS date, m.categorie AS droitsmembre, m.id AS idmembre
    FROM categories AS ca LEFT JOIN membres AS m ON m.id=ca.idmembre
    LEFT JOIN competences AS co ON co.type="spe" AND co.idcategorie=ca.id WHERE m.valide=1 AND ca.etat=1 AND ca.categorie="Développeur"
    


    Le resultat de cette requete donne ceci :
    Image utilisateur
    Or cela ne me convient pas puisque la requete affiche une ligne par competence et non pas par individu. Y'a-t-il une incohérence dans cette requête ?

    Merci d'avance !
    T'ry.

    PS : Merci à Tracker qui a tenté de m'aider mais apparament en vain...
    • Partager sur Facebook
    • Partager sur Twitter
      15 novembre 2010 à 22:05:05

      C'est ta jointure qui est mal faite. Tu prend comme base de référence la table catégories.
      Donc il sort une ligne par catégorie.

      Remplace dans le FROM categories par membres et fais les changements nécessaires.

      EDIT :
      Mais tu n'a pas de liaisons de membres vers categories donc il faut faire un RIGHT JOIN

      Ce qui donne

      SELECT co.competence, 
             co.type, 
             co.temps, 
             co.note, 
             co.id, 
             ca.dispo as dispo, 
             ca.refs, 
             m.pseudo, 
             ca.id AS idcategorie,
             ca.categorie, 
             DATE_FORMAT(datepostulation, "%d/%m/%Y") AS date, 
             m.categorie AS droitsmembre, 
             m.id AS idmembre
      FROM categories AS ca RIGHT JOIN membres AS m ON m.id=ca.idmembre
      LEFT JOIN competences AS co ON co.type="spe" AND co.idcategorie=ca.id 
      WHERE m.valide=1 AND ca.etat=1 AND ca.categorie="Développeur"
      


      C'est comme ça que je la vois. Après c'est à tester.
      • Partager sur Facebook
      • Partager sur Twitter
        15 novembre 2010 à 22:27:59

        Bonsoir Leo48 !

        Merci pour ton temps mais ta requête me donne exactement le même résultat !
        J'ai tenté avec la requête initiale d'inverser également catégorie et membre, ce qui parait logique et le résultat ne bronche pas !
        Je n'ai jamais vu cela ... Une idée ?

        T'ry.
        • Partager sur Facebook
        • Partager sur Twitter
          16 novembre 2010 à 0:27:36

          Si j'ai bien compris, tu voudrais 2 lignes plutôt que 5 ? Tu veux rassembler toutes les compétences pour chaque membre ? Dans ce cas-ci, tu vas devoir utiliser GROUP_CONCAT :

          SELECT GROUP_CONCAT(co.competence SEPARATOR ' ') AS competences, co.type, co.temps, co.note, co.id, ca.dispo, ca.refs, m.pseudo, ca.id AS idcategorie,
          ca.categorie, DATE_FORMAT(datepostulation, '%d/%m/%Y') AS date, m.categorie AS droitsmembre, m.id AS idmembre
          FROM categories AS ca 
          LEFT JOIN membres AS m 
              ON m.id = ca.idmembre
          LEFT JOIN competences AS co 
              ON co.idcategorie=ca.id 
              AND co.type="spe"
          WHERE 
              m.valide=1 
              AND ca.etat=1 
              AND ca.categorie="Développeur"
          GROUP BY co.type, co.temps, co.note, co.id, ca.dispo, ca.refs, m.pseudo, ca.id, ca.categorie, datepostulation, m.categorie, m.id
          


          Plus d'informations sur GROUP_CONCAT

          P.S. J'ai utilisé ta requête en supposant qu'elle était bonne.
          • Partager sur Facebook
          • Partager sur Twitter
            16 novembre 2010 à 17:29:07

            Oui tu as tout à fait compris :)
            J'ai testé ton code mais le problème persiste... Je remet donc en question l'affichage du tableau, y'aurait il une erreur à ce niveau là ?


            <?php
            $reqcat = mysql_query($req)or die(mysql_error());
            while($req1 = mysql_fetch_array($reqcat))
            {
            echo'<tr>
            <td>'.$req1['pseudo'].'</td>
            <td>
            '.$req1['competences'].' | 
            </td>
            <td>'.$req1['dispo'].'</td>
            <td>'.$req1['date'].'</td>';
            
            }
            ?>
            


            Une idée ??
            • Partager sur Facebook
            • Partager sur Twitter
              16 novembre 2010 à 17:52:16

              Avant de tester cette requête directement via PHP, je te suggère de l'essayer directement dans la console (ou dans l'onglet SQL de phpMyAdmin).

              Ça m'étonne que ça te retourne le même jeu de résultats. Faisons un exemple plus simple :
              mysql> CREATE TABLE test_group_concat (id integer, skill varchar(255));
              Query OK, 0 rows affected (0.01 sec)
              
              mysql> INSERT INTO test_group_concat VALUES (1, 'PHP'), (1, 'HTML'), (1, 'CSS'), (2, 'SQL'), (2, 'C++'), (3, 'C');
              Query OK, 6 rows affected (0.00 sec)
              Records: 6  Duplicates: 0  Warnings: 0
              
              mysql> SELECT id, GROUP_CONCAT(skill SEPARATOR ' | ') AS skills
                  -> FROM test_group_concat
                  -> GROUP BY id;
              +------+------------------+
              | id   | skills           |
              +------+------------------+
              |    1 | PHP | HTML | CSS |
              |    2 | SQL | C++        |
              |    3 | C                |
              +------+------------------+
              3 rows in set (0.00 sec)


              C'est le même principe avec une table plus grosse. Le seul problème que je peux voir, c'est que toutes les colonnes ne sont pas toutes égales (sauf compétences, évidemment). Est-ce que tu pourrais nous montrer tout ce que la requête retourne (toutes les colonnes, au moins) ?
              • Partager sur Facebook
              • Partager sur Twitter
                16 novembre 2010 à 18:03:28

                C'est vraiment etrange !
                Cependant la particularité est que les compétences constituent des entrées différent même si elles concernent le meme membre :
                Image utilisateur

                Voila comme tu l'a demandé le rendu de ta requête :

                Image utilisateur

                Franchement je patauge >< ^^


                EDIT : Je confirme que dans l'onglet SQL la requete demande bien d'afficher en fonction du nombre de competence qui existe et non pas par membre ! Voila un screen de ce que me renvoit MYSQL :
                Image utilisateur
                • Partager sur Facebook
                • Partager sur Twitter
                  16 novembre 2010 à 18:28:21

                  Ok, le problème vient effectivement de là : les id / idcategorie / type / temps / note ne sont pas égaux. Dans ce cas-ci, puisque apparemment tu n'en as pas besoin, tu peux faire simplement ceci :

                  SELECT GROUP_CONCAT(co.competence SEPARATOR ' ') AS competences, ca.dispo, m.pseudo, DATE_FORMAT(datepostulation, '%d/%m/%Y') AS date, m.id AS idmembre
                  FROM categories AS ca 
                  LEFT JOIN membres AS m 
                      ON m.id = ca.idmembre
                  LEFT JOIN competences AS co 
                      ON co.idcategorie=ca.id 
                      AND co.type="spe"
                  WHERE 
                      m.valide=1 
                      AND ca.etat=1 
                      AND ca.categorie="Développeur"
                  GROUP BY ca.dispo, m.pseudo,datepostulation, m.id
                  


                  En fait, GROUP BY groupe tous les éléments identiques ensemble. Donc si un seul est différent des autres, le SGBDR ne peut pas tous les grouper. Essaie cette requête et si ça ne fonctionne pas, essaie de sélectionner moins de colonnes pour voir ce qui se passe.

                  Si tu avais réellement besoin des autres colonnes, la requête va devenir beaucoup plus compliquées (et il va probablement avoir des doublons), mais ça doit être possible.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 novembre 2010 à 18:39:02

                    J'en ai les larmes aux yeux de voir ce script fonctionner !!!
                    J'ai enfin compris, en tout cas je n'aurais jamais trouver tout seul :)

                    Merci Merci et Merci encore !
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Requête SQL incontrolable

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown