Partage
  • Partager sur Facebook
  • Partager sur Twitter

Organiser ses requêtes SQL en fonction de 4 var

4 variables à l'état 0 ou 1, 16 requêtes possible, coder ça proprement

Sujet résolu
    5 mai 2021 à 18:08:57

    Salut à tous ! 

    Déjà je m'excuse par avance si le sujet à déjà était posé mais j'ai du mal à formuler ma requête succinctement et je n'ai rien trouvé sur le forum.

    Alors je m'explique, en résumé : 

    j'ai une table composée de 4 champs, et un formulaire de 4 champs également. En fonction de si ces champs ( du formulaire ) sont remplis ou non, ma requête devra évoluée. C'est une requête avec un (ou plusieurs) simple WHERE quand le champ est rempli, et aucun quand il(s) ne le sont pas. En gros les variables associées à mes champs peuvent être à 0 ou 1 suivant si elles sont remplies ou non. Et en fait je me vois mal faire 16 if pour tout les cas de figures. Je sais qu'il y a le switch, mais j'ai un peu de mal à me projeter l'utilisation d'un switch en vérifiant 4 valeurs. 

    Le truc c'est que j'aimerai coder sa proprement, donc si quelqu'un à une astuce, un chemin vers lequel me tourner je suis preneur ! (array pour le switch, une requête mysql mieux formuler etc)

    Merci d'avance ! :D (si besoin est, j'imagerais mes propos avec le code et la table en question)

    • Partager sur Facebook
    • Partager sur Twitter
      5 mai 2021 à 18:16:05

      Il suffit de procéder avec ce principe :

      $conds = ['1=1'];
      $binds = [];
      
      if (!empty($_POST['champ1'])) {
          $conds[] = 'colonne1 = :colonne1';
          $binds['colonne1'] = $_POST['champ1'];
      }
      if (!empty($_POST['colonne2'])) {
          $conds[] = 'colonne2 = :colonne2';
          $binds['colonne1'] = $_POST['champ1'];
      }
      // ...
      # si jamais les noms des champs étaient les mêmes que les colonnes :
      foreach (['colonne1', 'colonne2', /* ... */] as $c) {
          if (!empty($_POST[$c])) {
              $conds[] = "$c = :$c";
              $binds[$c] = $_POST[$c];
          }
      }
      
      $stmt = $bdd->prepare('SELECT * FROM table WHERE ' . implode(' AND ', $conds) . ' ORDER BY date DESC');
      $stmt->execute($binds);
      

      PS : une requête n'a qu'une clause WHERE, pas plusieurs

      -
      Edité par julp 6 mai 2021 à 11:30:31

      • Partager sur Facebook
      • Partager sur Twitter
        5 mai 2021 à 18:19:00

        J'ai 4 variables pouvant être à 0 ou 1, soit 2^4 possibilités, je dois donc faire 16 if ? c'est la première idée que j'avais eu mais ça me paraissait barbare...
        • Partager sur Facebook
        • Partager sur Twitter
          5 mai 2021 à 18:23:34

          Non, 4 champs/colonnes = 4 if, éventuellement avec un else (ou des ternaires si ça s'y prête) si la valeur n'est pas remplie et que tu dois quand même avoir une condition différente en clause WHERE. 16 conditions seraient nécessaires que si les champs étaient interdépendants (ie chaque combinaison de champs devait se voir associée à une valeur différente/spécifique)

          Un exemple (les requêtes à obtenir) avec une colonne ?

          -
          Edité par julp 5 mai 2021 à 18:33:12

          • Partager sur Facebook
          • Partager sur Twitter
            6 mai 2021 à 8:59:57

            Alors en gros ma table est composé d'un client, la date de son appel, le technicien qui s'est occupé de lui, et une option que j'ai appelé "fusion" qui permet de fusionner le temps de communication de tous ses appels ou de les détailler.

            Donc un champ client, un champ date, un champ tech, un champ fusion. Ma requête doit évoluer si ces champs sont remplis ou non, afficher tous les clients, ou seulement celui qu'on entre, est ce qu'on fusionne leur appel ou est-ce qu'on les détails, un technicien en particulier qui s'est occupé de lui oui tous, à une date défini où n'importe quand.

            En requête ça nous ferait donc :

            $req = $bdd->query('SELECT * FROM hotline ORDER BY dateCommunication DESC'); si rien n'est rempli

            $req = $bdd->query('SELECT * FROM hotline WHERE technician="techName" ORDER BY dateCommunication DESC'); si on remplis juste le champ tech

            $req = $bdd->prepare('SELECT * FROM hotline WHERE technician = :technician AND dateCommunication >= :dateDu AND dateCommunication <= :dateAu'); si on précise la date et le tech

            etc

            • Partager sur Facebook
            • Partager sur Twitter
              6 mai 2021 à 11:58:29

              Ca correspond exactement à ce que je t'ai proposé :

              $conds = ['1=1'];
              $binds = [];
              
              if (!empty($_POST['tech'])) {
                  $conds[] = 'technician = :technician';
                  $binds['technician'] = $_POST['tech'];
              }
              if (!empty($_POST['dateDu'])) {
                  $conds[] = 'dateCommunication >= :dateDu';
                  $binds['dateDu'] = $_POST['dateDu'];
              }
              if (!empty($_POST['dateAu'])) {
                  $conds[] = 'dateCommunication <= :dateAu';
                  $binds['dateAu'] = $_POST['dateAu'];
              }
              
              $stmt = $bdd->prepare('SELECT * FROM hotline WHERE ' . implode(' AND ', $conds) . ' ORDER BY dateCommunication DESC');
              $stmt->execute($binds);


              J'ai juste un doute sur un détail : je ne suis pas sûr que PDOStatement::execute accepte un tableau vide (donc quand tous les champs sont vides)

              -
              Edité par julp 6 mai 2021 à 13:31:06

              • Partager sur Facebook
              • Partager sur Twitter
                6 mai 2021 à 12:07:07

                Ah pardon j'avais pas compris la première fois ! En effet ça me semble mieux que 16 if ahah, j'essaye ça et je reviens faire le retour ici. Merci beaucoup en tout cas

                EDIT : 

                Petit retour sur ta solution.

                Déjà tout fonctionne à merveille, merci pour cette solution.

                Pour ton doute, dans mon cas j'utilise des boutons radio en html pour les techniciens, donc par défaut si aucun techniciens n'est coché, c'est "Tous" qui est coché donc mon tableau ne sera jamais vide. En revanche pour t'ôter de ton doute, si le tableau est vide cela fonctionne malgré tout, en tout cas chez moi avec PDO.

                Je vous laisse avec mon formulaire HTML ainsi que le code PHP associé si cela peut servir à quelqu'un dans le futur, et je clos le sujet en fin de journée ou demain si il n'y pas d'autres messages. Hésitez pas si quelqu'un a des remarques d'ici là. Encore merci :D

                <h2>Historique hotline :</h2>
                
                							<h3>Filtres :</h3>
                							<div>
                								<form method="POST" action="filtres.php">
                									<div class="row gtr-uniform">
                										<div class="col-12 col-12-xsmall">
                											<p>Technicien :</p>
                											<input type="radio" name="technician" id="tous" value="tous" checked>
                											<label for="tous">Tous</label>
                											<input type="radio" name="technician" id="mathieu" value="mathieu" >
                											<label for="mathieu">Mathieu</label>
                											<input type="radio" name="technician" id="stephane" value="stephane" >
                											<label for="stephane">Stéphane</label>
                											<input type="radio" name="technician" id="yann" value="yann" >
                											<label for="yann">Yann</label>
                										</div>
                										<div class="col-3 col-12-xsmall">
                											<label class="filtres" for="dateDu">Du : </label>
                											<input type="date" name="dateDu" id="dateDu">
                										</div>
                										<div class="col-3 col-12-xsmall">
                											<label class="filtres" for="dateAu">Au : </label>
                											<input type="date" name="dateAu" id="dateAu">
                										</div>
                										<div class="col-3 col-12-xsmall">
                											<input type="text" name="client" id="search" autocomplete="off" value="" placeholder="Client" />
                											<div id="result"></div>
                										</div>
                										<div class="col-3 col-12-xsmall">
                											<input type="checkbox" name="fusionClient" id="fusionClient" value="fusion">
                											<label class="fusionClient" for="fusionClient">Fusionner par client</label>
                										</div>
                										<div class="col-2 col-12-xsmall">
                											<input class="primary" type="submit" value="Appliquer">
                										</div>
                										<div class="col-2 col-12-xsmall">
                											<a href="consulthotline.php" class="button" id="">Réinitialiser</a>
                										</div>
                									</div>
                								</form>
                							</div>
                try 
                {
                 	$bdd = new PDO('mysql:host=localhost; dbname=intranet; charset=utf8', '****', '****');
                }
                catch (Exception $e)
                {
                 	die('Erreur : ' . $e->getMessage());
                }
                
                $conds = ['1=1'];
                $binds = [];
                 
                if (!empty($_POST['technician']))
                {
                	if ($_POST['technician'] == 'tous')
                	{
                		//on prend pour tous les techs
                	}
                	else
                	{
                    $conds[] = 'technician = :technician';
                    $binds['technician'] = $_POST['technician'];
                    }
                }
                if (!empty($_POST['dateDu']))
                {
                    $conds[] = 'dateCommunication >= :dateDu';
                    $binds['dateDu'] = $_POST['dateDu'];
                
                    $conds[] = 'dateCommunication <= :dateAu';
                    $binds['dateAu'] = $_POST['dateAu'];
                }
                if (!empty($_POST['client']))
                {
                    $conds[] = 'client = :client';
                    $binds['client'] = $_POST['client'];
                }
                // if (!empty($_POST['fusion']))
                // {
                //     $conds[] = 'fusion <= :fusion';
                //     $binds['fusion'] = $_POST['fusion'];
                // }
                 
                $req = $bdd->prepare('SELECT * FROM hotline WHERE ' . implode(' AND ', $conds) . ' ORDER BY dateCommunication DESC');
                $req->execute($binds);



                -
                Edité par Anlon 6 mai 2021 à 16:44:27

                • Partager sur Facebook
                • Partager sur Twitter

                Organiser ses requêtes SQL en fonction de 4 var

                × 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