La boucle while retourn plusieurs données

Résolu
bonjour , j'ai un souci avec ce code il retourne plusieurs fois les meme choses


<?php

                                include 'ca/codes/bdcon.php';

                      $req_join = 'SELECT DISTINCT  P.id_cata,lib_cata,img_prod,lib_prod
                            FROM marque M
                            LEFT JOIN produit P ON M.id_marq = P.id_marq
                            LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                            LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                             WHERE  statu_cata=1 order by lib_cata';
                             
                     
                         $envoi = $bd->query($req_join);
                         print_r($req_join);
                         while ($data=$envoi->fetch()) {
                             echo ' 
                             <li> <a class="mega-title" href="#" rel="nofollow noopener noreferrer" target="_blank">'.$data['lib_cata'].'</a></li>
                              <li> <a href="#" rel="nofollow noopener noreferrer" target="_blank">'.$data['lib_prod'].' </a></li>';
                         }

                             
                             ?>

20 réponses

Résumé de la discussion

Problème principal: une requête PHP/MySQL utilisant des jointures LEFT JOIN retourne plusieurs fois les mêmes éléments, ce qui génère des doublons dans les résultats et complique l'affichage. Des propositions variées émergent pour corriger la logique: modification de l'instruction SELECT, réorganisation des données en tableaux associatifs, et changement de l'affichage HTML pour éviter des balises répétées. Parmi les solutions proposées, plusieurs utilisateurs recommandent de regrouper les résultats par catégorie et de construire des tableaux avant l'affichage, afin d’éviter les duplicates et d’obtenir une présentation des catégories et produits. En outre, certains suggèrent de clarifier la structure des requêtes et des tables (id_cata, lib_cata, lib_prod) et d'ajuster WHERE afin de limiter les doublons et obtenir une correspondance précise entre catégories et produits.

Bobot (l’IA à votre service)
  1. Contributeur Ambassadeur
    bonsoir, et ainsi?
    SELECT DISTINCT  lib_cata, lib_prod
                                FROM marque M
                                LEFT JOIN produit P ON M.id_marq = P.id_marq
                                LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                 WHERE  statu_cata=1 order by lib_cata

    si tu veux une aide plus précise, je te suggère de décrire la structure de tes tables, et les "mêmes choses" retournées.
    nous ne voyons pas ce que tu vois, nous ne savons pas ce que tu sais.
    si tu ne nous donnes pas d'information, nous ne pouvons pas les deviner.
    0
    1.  $data['lib_cata'] retourne 6 element de meme nom c'est a dire si j'ai mis  accessoire il ya plusieurs fois accessoire.
      je veux qu'il affiche accessoire ensuite tout les element concernant accessoire .
      en d'autre tourne lister les enregistrements de catalogue 'accessoire,pc...' maintenant sous accessoire on affiche le nom du produit mais pas les meme nom du produit . 
      0
      1. Contributeur Ambassadeur
        ce que tu expliques est compliqué pour nous: nous connaissons lib_cata et lib_prod, et, dans ton message, tu utilises un autre vocabulaire.

        il est normal que ton code te donne, par exemple:
        cata1, prod1
        cata1, prod2
        cata2, prod1
        cata3, prod1
        cata1, prod3

        si tu veux obtenir autre chose, tu dois, soit faire d'autres requêtes à la base de données, soit, par programme, traiter le résultat reçu pour afficher ce que tu veux.
        tu peux cependant modifier la requête pour recevoir les résultats dans l'ordre, si nécessaire.
        0
    2. comment je fais parce que moi je veux afficher
      cata1,prod1 jusqu'a ----->prod N
      cata2,prod2 jusqu'a----->prod N
      cataN,prodn jusqu'a----->prod N
      0
      1. Contributeur Ambassadeur
        moi je ferais ainsi:
        1) retirer lib_prod de ta requête
        2) dans le while, faire une seconde requête qui va chercher tous les lib_prod correspondants au $data['lib_cata']. cette seconde requete va utiliser de nouvelles variables, disons $data2, $envoi2 et $req_join2
        3) suite à cette seconde requête, faire un second while (imbriqué dans le premier), qui va traiter $data['lib_cata'] et $data2['lib_prod']

        ta seconde requete serait qualque-chose comme:
        SELECT DISTINCT lib_prod
                                    FROM marque M
                                    LEFT JOIN produit P ON M.id_marq = P.id_marq
                                    LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                    LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                     WHERE  statu_cata=1 and lib_cata = ?
                                    order by lib_prod

        cela te permettre de te familiariser avec le concept de préparation d'une requête: tu pourras préparer la seconde requête hors des while.
        0
    3. je suis vraiment confus ..
      0
      1. j'ai retiré lib_prod ensuite l'autre explication je ne comprend pas
        
        $req_join='SELECT  lib_cata
                                    FROM marque M
                                    LEFT JOIN produit P ON M.id_marq = P.id_marq
                                    LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                    LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                     WHERE  statu_cata=1 order by lib_cata';
                                 $envoi = $bd->query($req_join);
        
                                 while ($data=$envoi->fetch()) {
                                     echo ' 
                                     <li> <a class="mega-title" href="#" rel="nofollow noopener noreferrer" target="_blank">'.$data['lib_cata'].'</a></li>
                                      <li> <a href="#" rel="nofollow noopener noreferrer" target="_blank">'.$data['lib_prod'].' </a></li>';
                                 }
        
        0
        1. Contributeur Ambassadeur
          je te donne des explications générales et des suggestions.
          si tu ne les comprends pas, je te suggère de faire d'abord des exercices plus simples.
          je pense que cela te permettra de mieux progresser en php et en sql.
          0
      2. ok mais votre suggestion je n'ai pas compris je veux reussir celui la les autres exercices je les fais je suis un peu perdu c'est pour cela je poste ici
        0
        1. allons pas à pas je vais comprendre , une histoire de 2 boucle while , je n'ai pas encore rencontrer un probleme pareil
          0
          1. Contributeur Ambassadeur
            ok, essayons:

            tu prends une copie des lignes de code qui commencent en $req_join et qui se terminent au }.

            tu remplaces dans le code original les lignes de echo jusqu'au ; par le code que tu as copié

            dans le code que tu viens d'insérer, tu ajoutes 2 derrière le nom de chaque variable, sauf $bd

            tu remplaces le code
            $req_join2='SELECT  lib_cata
                                        FROM marque M
                                        LEFT JOIN produit P ON M.id_marq = P.id_marq
                                        LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                        LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                         WHERE  statu_cata=1 order by lib_cata';

            par
            $req_join2='SELECT DISTINCT lib_prod
                                        FROM marque M
                                        LEFT JOIN produit P ON M.id_marq = P.id_marq
                                        LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                        LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                         WHERE  statu_cata=1 and lib_cata = "' . $data['lib_cata' ] .
                                        '" order by lib_prod';


            tu partages le code obtenu
            0
        2. Modérateur
          Bonjour,

          A partir de ton code d'origine ...
          Deux solutions s'offrent à toi ...
          Soit... tu gères avec des IF pour voir si, lorsque tu parcours ta boucle, la "cata" précédente égale celle que tu vas afficher (si oui.. tu ne l'affiche pas...)

          Soit .. c'est plus simple... tu passes par un tableau intermédiaire.
          Un truc du genre :
          
          <?php
          
          require_once 'ca/codes/bdcon.php';
          
          $req_join = 'SELECT DISTINCT  P.id_cata,lib_cata,img_prod,lib_prod
                        FROM marque M
                        LEFT JOIN produit P ON M.id_marq = P.id_marq
                        LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                        LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                        WHERE  statu_cata=1 order by lib_cata';
          
          
          $envoi = $bd->query($req_join);
          print_r($req_join);
          
          
          // on retravaille l'array de sorti pour avoir un array plus simple à utiliser
          $arrTmp = array();
          while ($data=$envoi->fetch()) {
            $arrTmp[$data['id_cata']]['lib_cata'] = $data['lib_cata'];
            $arrTmp[$data['id_cata']]['prod'][] = array('img'=>$data['img_prod'],'lib_prod'=>$data['lib_prod']); 
          }
          
          //tableau remis en forme :
          print_r($arrTmp);
          
          //je boucle sur le nouvel array pour faire l'affichage
          if(!empty($arrTmp)){
            foreach($arrTmp as $id_cata=>$Cata){
              echo '<li> 
                      <a class="mega-title" href="#" rel="nofollow noopener noreferrer" target="_blank">'.$Cata['lib_cata'].'</a>
                    </li>';
            
              $arr_prod = !empty($Cata['prod']) ? $Cata['prod'] : NULL;
              //si il y a des produits...
              if($arr_prod){
                foreach($arr_prod as $prod){
                  echo '<li> 
                         <a class="mega-title" href="#" rel="nofollow noopener noreferrer" target="_blank">'.$prod['lib_prod'].'</a>
                        </li>';
                }
              }
            }
          }
          
          

          0
          1. ok merci
            0
            1. Contributeur Ambassadeur
              si résolu, peux-tu marquer comme résolu?
              0
          2. je veux les placer dans un tableau j'ai essayer cela ne me donne rien de bon tout es desordonné !!!!

            IMPRIMANTE ACCESSOIRE
            |-------------| | ---------|
            -Canon -Ecouteur
            -hp -...........

            ce genre d'affichage je veux
            0
            1. Modérateur
              Tu as essayé quoi au juste ?
              (montres ton code !!! )
              Tu obtiens quoi actuellement ??

              Quand tu parles de "tableau" .. tu veux parler d'un ARRAY ou d'une "table" html ???
              Merci d'être plus précis !
              0
          3. non non je parle de <table>
            0
            1. 
              <?php
              
              require_once 'ca/codes/bdcon.php';
              
              $req_join = 'SELECT DISTINCT  P.id_cata,lib_cata,img_prod,lib_prod
                            FROM marque M
                            LEFT JOIN produit P ON M.id_marq = P.id_marq
                            LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                            LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                            WHERE  statu_cata=1 order by lib_cata';
              
              
              $envoi = $bd->query($req_join);
              //print_r($req_join);
              
              
              // on retravaille l'array de sorti pour avoir un array plus simple à utiliser
              $arrTmp = array();
              while ($data=$envoi->fetch()) {
                $arrTmp[$data['id_cata']]['lib_cata'] = $data['lib_cata'];
                $arrTmp[$data['id_cata']]['prod'][] = array('img'=>$data['img_prod'],'lib_prod'=>$data['lib_prod']); 
              }
              
              //tableau remis en forme :
              //print_r($arrTmp);
              
              //je boucle sur le nouvel array pour faire l'affichage
              if(!empty($arrTmp)){
                foreach($arrTmp as $id_cata=>$Cata){
                  echo '<table border="1"><thead><tr><th> <li> 
                          <a class="mega-title" href="#" rel="nofollow noopener noreferrer" target="_blank">'.$Cata['lib_cata'].'</a>
                        </li></th></tr></thead> ';
                
                  $arr_prod = !empty($Cata['prod']) ? $Cata['prod'] : NULL;
                  //si il y a des produits...
                  if($arr_prod){
                    foreach($arr_prod as $prod){
                      echo '<tbody><tr><td><li> 
                             <a href="#" rel="nofollow noopener noreferrer" target="_blank">'.$prod['lib_prod'].' </a>
                            </li></td></tr></tbody></table>';
                    }
                  }
                }
              }                             ?>
              
              

              les $Cata['lib_cata'] je veux les afficher en horizontal car c'est dans un menu deroulant et sous les $Cata['lib_cata'] leur produit correspondant dans les <a href="..." rel="nofollow noopener noreferrer" target="_blank"> obtenir leur id pour afficher le produit correspondant au choix de l'utilisateur
              0
              1. Modérateur
                Je ne comprend pas trop....
                Là actuellement .. tu créés un TABLEAU par $Cata['lib_cata']
                Mais toi.. tu veux que ça soit présenté comment exactement ?
                Montre nous le code HTML que tu souhaites avoir en sorti ...
                par exemple :
                <table>
                  <thead>
                    <tr>
                      <th> TOTO</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                       <td> Produit 1 </td>
                       <td> Produit 2 </td>
                       <td> Produit ... </td>
                    </tr>
                  </tbody>
                </table>
                
                <table>
                  <thead>
                    <tr>
                      <th> TITI </th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                       <td> Produit 1 </td>
                       <td> Produit 2 </td>
                       <td> Produit ... </td>
                    </tr>
                  </tbody>
                </table>
                
                0
            2. ce model
               <table>
                <thead>
                  <tr>
                    <th> TOTO</th>
                    <th> TITI </th>
                      <th> TATA </th>
                  </tr>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                     <td> Produit 1 </td>
                     <td> Produit 1 </td>
                     <td> Produit 1 </td>
                  </tr>
                 <tr>
                     <td> Produit 2 </td>
                     <td> Produit 2 </td>
                     <td> Produit ...</td>
                  </tr>
                   <tr>
                     <td> Produit 3 </td>
                     <td> Produit 3 </td>
                     <td> Produit ... </td>
                  </tr>
                </tbody>
              </table>
              
              
              0
              1. Une idée de comment je peux m'y prendre??
                0
                1. Modérateur
                  Oui.
                  0
                2. Modérateur
                  @jordane45Il te suffit de faire deux boucles
                  Une pour generer les th
                  Puis une pour replir le body avec les tr et les td
                  0
              2. Ce sont les boucles de mon code ou-bien je dois en faire autre ?
                0
                1. J'ai introduit dans le code précédent tout es désordonné ou c'est moi j'ai mal placer regardé
                  0
                  1. Je ne m'en sort vraiment pas ! Avec le tableau
                    0
                    1. Modérateur
                      1 - Arrête d'éditer tes messages précédents pour y mettre ton code modifié !
                      Déjà parceque les messages que nous avons posté en dessous n'ont plus aucun sens.. et ensuite par-ce que c'est casse pied de sans cesse devoir scroller de bas en haut pour regarder le code ...

                      2 - Tu fais n'importe quoi dans ton code..... Faudrait vraiment que tu commences par (ou apprendre les bases du langage que tu ne maitrise clairement pas..... ou que tu prennes au moins le temps d'essayer de comprendre ce que tu fais ! )
                      Tu ne vas pas me dire que ceci ne te choque pas :
                      foreach($arr_prod as $prod){
                              echo '<tbody><tr><td><li> 
                      

                      Te rends tu compte que dans la boucle ... tu génère des tbody à chaque tour de la boucle ??? .... sais tu au moins comment est sensé être structuré une TABLE html ?????

                      3 - Ca ne sert à rien (hormis m'agacer....) de venir poster un message toutes les deux heures pour faire des "up" .... Déjà ça ne nous fera pas répondre plus vite (bien au contraire....) et ensuite.... au lieu de faire des UP tu devrais nous montrer où tu en es. Ce n'est pas possible qu'entre 17h04 et 19h24 tu n'aies rien essayé ..... ou alors tu attend qu'on te donne le code tout fait ???? (mais là... ce n'est pas notre façon de faire habituelle !!!!! )

                      4 - Ta question de départ ne concernait en rien un TABLEAU. tu étais sur des listes ( <ul><li>... ).
                      Normalement.... tu aurais du ouvrir une nouvelle discussion et non pas poser ta "nouvelle" question dans celle là !

                      5 - Comme je sens que si je ne te donne pas un debut de code... tu n'avanceras pas plus... voila ;
                      Essaye ça
                      
                      <?php
                      
                      require_once 'ca/codes/bdcon.php';
                      
                      $req_join = 'SELECT DISTINCT  P.id_cata,lib_cata,img_prod,lib_prod
                                    FROM marque M
                                    LEFT JOIN produit P ON M.id_marq = P.id_marq
                                    LEFT JOIN catalogue CA ON CA.id_cata = P.id_cata
                                    LEFT JOIN couleur  CO ON CO.id_prod = P.id_prod
                                    WHERE  statu_cata=1 order by lib_cata';
                      
                      
                      $envoi = $bd->query($req_join);
                      //print_r($req_join);
                      
                      
                      // on retravaille l'array de sorti pour avoir un array plus simple à utiliser
                      $a_colonnes = array();
                      $arr_body = array();
                      while ($data=$envoi->fetch()) {
                        $a_colonnes[$data['id_cata']] = $data['lib_cata'];
                        $arr_body[] = array('img'=>$data['img_prod'],'lib_prod'=>$data['lib_prod']); 
                      }
                      
                      //tableau remis en forme :
                      //print_r($arrTmp);
                      
                      
                      echo "<table>
                             <thead>
                             <tr>";
                      if(!empty($a_colonnes)){
                        foreach($a_colonnes as $id_cata=>$Cata){
                          echo "<th>".$Cata."</th>";
                        }
                      }
                      echo "</tr>
                            </thead>
                            <tbody>";
                            
                      if(!empty($arr_body)){
                        foreach($arr_body as $row){
                          echo "<tr>";
                          if(!empty($arr_body)){
                            foreach($row as $prod){
                              echo "<td>".$prod['lib_prod']."</td>";
                            }
                          }
                          echo "</tr>";
                          
                        }
                      }                      
                      
                      echo "</tbody>
                            </table>";
                       ?>
                      
                      


                      NB: Je te laisse le compléter selon tes besoins.
                      Merci de mettre cette discussion en Résolu et d'en ouvrir une nouvelle pour ta prochaine question.

                      NB² : Dans ta prochaine question... essaye de t'appliquer pour expliquer ce que tu as fait et ce que tu VEUX faire... Histoire qu'on ne perdre pas autant de temps que cette fois ci.

                      0
                      1. Contributeur Ambassadeur
                        je pense que delavega470 voudrait ceci:
                        si le select renvoie
                        c1 c1p1
                        c1 c1p2
                        c1 c1p3
                        c2 c2p1
                        c2 c2p2
                        c3 c3p1

                        il voudrait un tableau:
                        c1   c2   c3
                        c1p1 c2p1 c3p1
                        c1p2 c2p2
                        c1p3 
                        0
                    2. Désolé si je vous agasse.
                      0
                      1. Contributeur Ambassadeur
                        inutile d'être désolé.
                        regarde ce que tu expliquais eu début, puis ce que tu as expliqué en #4, et puis ce que tu expliques ensuite. ce que tu voudrais a changé (au moins) trois fois.
                        ce serait plus respectueux pour nous si tu prenais le temps de bien tout expliquer dès le début, ne trouves-tu pas?
                        0