Partage
  • Partager sur Facebook
  • Partager sur Twitter

Selectionner une seule fois un id dans une Bdd sql

    24 janvier 2017 à 10:09:00

    Bonjour,

    Je suis en train de creer un formulaire avec des checkbox allant chercher des matériaux dans une bdd. Après selection des checkbox (en tableau), un foreach test chaque colonne (il y en a 4) pouvant contenir le matériau selectionné (:element).

    Le problème est que si une ligne possède plusieurs matériaux selectionnés, elle apparait alors plusieurs fois dans ma fonction echo suivante. Comment pourrais-je selectionner une seule fois la ligne à partir du moment où elle possède un matériau selectionné?

    Merci de votre aide, 

    Mon code ci-dessous:

    <?php
    try
    {
    	$bdd = new PDO('mysql:host=localhost;dbname=bddtest;charset=utf8', 'root', '');
    }
    catch(Exception $e)
    {
            die('Erreur : '.$e->getMessage());
    }
    if (isset($_POST['materiau']))
    { 
    $tabcheckbox = $_POST['materiau'];
    foreach ($tabcheckbox as $checkbox) 
    	{
    	$element = addslashes($checkbox);
    
    $req = $bdd->prepare('SELECT * FROM chantier WHERE materiau_1 = :element OR materiau_2 = :element OR materiau_3 = :element OR materiau_4 = :element');
    $req->execute(array('element' => $element));
    
    while ($donnees = $req->fetch())
    		{
    				
    	echo $donnees['id'] . $donnees['societe'] . ' - ' . $donnees['nom_contact'] .$donnees['materiau_1'] .$donnees['materiau_2'] .$donnees['societe_type'] . '<br />';
    		}
    	}
    	$req->closeCursor();
    }
    else
    {echo 'Sélectionnez au moins un matériau!';}
    
    ?>
    • Partager sur Facebook
    • Partager sur Twitter
      24 janvier 2017 à 10:19:41

      Salut !

      A moins que tu puisses avoir plusieurs fois le même matériau qui soit listé, je pense que tu peux ajouter le mot-clé DISTINCT entre SELECT et *.

      • Partager sur Facebook
      • Partager sur Twitter
        24 janvier 2017 à 10:48:51

        Bonjour,

        Merci de ta réponse. Malheureusement, ça ne fonctionne pas. Effectivement, une ligne ne peut avoir qu'une seule fois le matériau. 

        J'ai essayé avec GROUP BY id en fin de SELECT mais ça ne fonctionne pas non plus.

        J'ai l'impression qu'il faut que je mette une condition dans la boucle WHILE lui disant de ne pas reselectionner un id déja choisi mais je ne vois pas comment l'écrire.

        • Partager sur Facebook
        • Partager sur Twitter
          24 janvier 2017 à 11:18:46

          Bonjour,

          Pourquoi ne pas mettre directement les id de tes matériaux en valeur de tes checkbox, ainsi la recherche est effectuée sur un id unique et pas sur une chaîne qui peut être en doublon dans ta table.

          • Partager sur Facebook
          • Partager sur Twitter
            24 janvier 2017 à 11:34:08

            Bonjour adrienrosi, 

            En fait les matériaux ne sont pas les lignes de la Bdd mais apparaissent dans les colonnes. Pour illustrer:

            id: 1 - societe: societe1 - nom_contact: contact1 - matériau_1: (TV-Deblais ou béton)-matériau_2:  (TV-Deblais ou béton) - materiau_3:  (TV-Deblais ou béton) etc...

            id: 2 - societe: societe2 - nom_contact: contact2 - matériau_1: (TV-Deblais ou béton)-matériau_2:  (TV-Deblais ou béton) - materiau_3:  (TV-Deblais ou béton) etc...

            Voici ci-dessous à quoi ressemble le code des checkbox:

            h3>Quels matériaux recherchez-vous ?</h3><br /> <!--Matériaux recherchés-->
            						
            						<input type="checkbox" name="materiau[]" value="TV" /> <label for="TV">Terre végétale</label><br /><br />
            						<input type="checkbox" name="materiau[]" value="deblais" /> <label for="deblais">Déblais</label><br /><br />
            						<input type="checkbox" name="materiau[]" value="beton" /> <label for="beton">beton</label><br /><br />



            • Partager sur Facebook
            • Partager sur Twitter
              24 janvier 2017 à 11:37:37

              Hello, 

              Tu peux aussi regarder le XOR au lieux du OR standard.

              Le XOR est un ou exclusif, qui ne te retournera, si je te dis pas de bêtises, uniquement le premier enregistrement trouvé.

              Pour comprendre, il agit comme "uniquement ça, ou alors uniquement ça".

              • Partager sur Facebook
              • Partager sur Twitter
              Kwo:re / topic OC | Aidez les autres, indiquez un sujet résolu ! | Vous êtes bloqué ? Suivez le guide ! | N'aide pas par MP
                24 janvier 2017 à 11:56:23

                Ealon, Bonjour, 

                Avec XOR, il exclut par rapport aux matériaux selectionnés mais sur une même ligne. J'ai testé le resultat est le même.

                Mon problème vient que un site, identifié par son id, peut avoir plusieurs matériaux selectionnés, il apparait alors dans l'echo autant de fois qu'il possède des matériaux sélectionnés. Si on selection TV et déblais, si il a dans materiau_1: TV et dans materiau_2: deblais, il apparaitra deux fois.  

                • Partager sur Facebook
                • Partager sur Twitter
                  24 janvier 2017 à 14:26:32

                  Dans ce cas, il se peut aussi que ton architecture ne soit pas idéale pour ton projet.

                  Pourquoi de ne pas faire une table 'sites' et une table 'materiaux', et avec un système de clés, attribuer un couple site/matériaux ...

                  Si je ne suis pas clair, dis moi

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Kwo:re / topic OC | Aidez les autres, indiquez un sujet résolu ! | Vous êtes bloqué ? Suivez le guide ! | N'aide pas par MP
                    24 janvier 2017 à 15:13:13

                    L'architecture n'est pas bonne. Tu devrais avoir une table 'societe', avec un ID unique pas société, et une table 'site' avec une clé étrangère id_societe par site, et éventuellement une table 'matériau' avec en clé étrangère id_site qui recense un matériau par ligne.

                    EDIT : l'idée dans la conception des tables, c'est qu'une table ne doit pas pouvoir être scindée. Si c'est le cas, c'est que tu regroupes dans une table ce qui devrait être dans plusieurs.

                    -
                    Edité par adrienrosi 24 janvier 2017 à 15:15:49

                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 janvier 2017 à 17:16:27

                      Bonsoir,

                      Alors j'ai divisé ma table en deux et je les ai jointes dans ma requete sql. c'est effectivement plus propre mais j'ai toujours mon souci de répetition. J'ai fait plusieurs tests et il me semble que le problème vient de mon foreach. 

                       Je pensais donc le remplacer par un implode avec un IN. J'ai beau tourner mon code, il ne cesse de planter. Le voici ci-dessous. J'ai shunter la partie formulaire en créant un array pour faire les tests.


                      <?php
                      
                      try
                      {
                      	$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
                      }
                      catch(Exception $e)
                      {
                              die('Erreur : '.$e->getMessage());
                      }
                      
                      // création d'un tableau
                      $tabcheckbox = array ('TV', 'Deblais', 'Beton');
                      
                      $element = ("\'".implode("\', \'", $tabcheckbox)."\'");
                      			
                      echo $element. '<br />'; // juste pour voir comment se fait le implode
                      
                      $req = $bdd->query('SELECT * FROM materiau WHERE materiau_1 IN ("\'".implode("\', \'", $tabcheckbox)."\'")'); // pour simplifier je n'ai mis qu'une table dans cet exemple
                      
                      while ($donnees = $req->fetch())
                      		{
                      			
                      				
                      	echo 'id' . $donnees['id'] .  'id_site' . $donnees['id_site']
                      	 . ' materiau 1: ' . $donnees['materiau_1'] . ' materiau 2: ' . $donnees['materiau_2'] 
                      	 . ' materiau 3: ' . $donnees['materiau_3'] . '<br />';
                      		}
                      	
                      	$req->closeCursor();
                      
                      
                      ?>


                      "Fatal error: Call to a member function fetch() on boolean ". Je précise que tout fonctionne si je remplace l'implode par: (\'TV\', \'Deblais\', \'Beton\')

                      Est-ce que vous voyez l'erreur?

                      -
                      Edité par Tonio09 25 janvier 2017 à 14:27:56

                      • Partager sur Facebook
                      • Partager sur Twitter
                        25 janvier 2017 à 17:52:05

                        Bonjour,

                        Est-ce que selon vous je fais fausse route avec implode? Je génère pleins d'erreur probablement en raison des apostrophes et guillemets.

                        Y a-t-il une solution pour que le IN fonctionne malgré les \'?

                        • Partager sur Facebook
                        • Partager sur Twitter
                          26 janvier 2017 à 8:48:36

                          Bonjour,

                          Si tu souhaites récupérer toutes les lignes de la table 'materiau' pour chaque ligne de ton array $tabcheckbox, fais un foreach sur ce dernier, insère ta requête SQL, et stockes les données renvoyées dans un autre tableau préalablement défini (array_push).

                          Oublie ton système implode et ton while pour l'affichage, fais juste un var_dump de ton tableau qui stockera tous les résultats.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Selectionner une seule fois un id dans une Bdd sql

                          × 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