Partage
  • Partager sur Facebook
  • Partager sur Twitter

Between et MSQL

borne incorrecte

Sujet résolu
    16 septembre 2011 à 21:34:40

    Bonjour,

    J'ai un petit soucis concernant les borne d'une requête msql avec des valeur alphabetique utilisées avec BETWEEN
    voici le bout de mon code qui pose problème:



    <?php
    /* VARIABLE DE PAGINATION ALHPABETIQUE */
    if (isset ($_POST ['nom']))
    	{	/*Définition des limites d'affichage alpha */
    		if ($_POST ['nom'] == "0-9") {$lim1 = "0"; $lim2 = "9";}
    		elseif ($_POST ['nom'] == "Tout") {$lim1 = "A"; $lim2 ="Z";}
    		elseif ($_POST ['nom'] == "A-C") {$lim1 = "A"; $lim2 = "C";}
    		elseif ($_POST ['nom'] == "D-F") {$lim1 = "D"; $lim2 = "F";}
    		elseif ($_POST ['nom'] == "G-I") {$lim1 = "G"; $lim2 = "I";}
    		elseif ($_POST ['nom'] == "J-L") {$lim1 = "J"; $lim2 = "L";}
    		elseif ($_POST ['nom'] == "M-P") {$lim1 = "M"; $lim2 = "P";}
    		elseif ($_POST ['nom'] == "Q-S") {$lim1 = "Q"; $lim2 = "S";}
    		elseif ($_POST ['nom'] == "T-V") {$lim1 = "T"; $lim2 = "V";}
    		elseif ($_POST ['nom'] == "W-Z") {$lim1 = "W"; $lim2 = "Z";}
    		else {header("Location: index.php");}
    	}
    else	
    	{	/*Par defaut pas de limite*/
    		$_POST ['nom'] = "Tout"; $lim1 = "A"; $lim2 ="Z";
    	}
    		
    <!--TABLEAU-->
    <table id="table-jneuf-choix">
    	<tr id="tajneufl1">
    	<?php
    	/***ligne numero un avec photo*******/
            $req = $bdd->prepare('SELECT * FROM jeux WHERE plateforme = :console AND nom BETWEEN :lim1 AND :lim2 ORDER BY nom ASC LIMIT :lim_aff_min,:nb_sujet_par_page');
    	$req->bindValue('console', $console, PDO::PARAM_INT);
    	$req->bindValue('lim1', $lim1, PDO::PARAM_STR);
    	$req->bindValue('lim2', $lim2, PDO::PARAM_STR);
    	$req->bindValue('lim_aff_min', $lim_aff_min, PDO::PARAM_INT);
    	$req->bindValue('nb_sujet_par_page', $nb_sujet_par_ligne, PDO::PARAM_INT);
    	$req->execute();
    	while ($neuf = $req->fetch())
    		{
    		if ($s == NULL){echo "<td><a href='form.php?id=".$neuf['id']."'><img src ='../image/".$_GET['im']."/".$neuf['id'].".jpg' alt='avatar'/></a></td>";}
    		if ($s == 1){echo "<td><a href='suppr.php?id=".$neuf['id']."'><img src ='../image/".$_GET['im']."/".$neuf['id'].".jpg' alt='avatar'/></a></td>";}
    		}
    ?>
    


    Le code a été racourci, l'ensemble des autres variable fonctionne parfaitement.

    Mon problème est le suivant:

    si je prend $_POST ['nom'] == "J-L" par exemple, donc $lim1 = "J" et $lim2 = "L".
    Le résultat de ma requete n'est pas correcte et ne compte pas L. C'est comme si sur chaque intervalle la limite supérieur était exclue du BETWEEN. Dans l'exemple ici le résultat donne tous les nom de jeux commencant par J, par K mais pas ceux commencant par L.

    Merci de vôtre aide.
    • Partager sur Facebook
    • Partager sur Twitter
      16 septembre 2011 à 22:42:55

      Parce que "Linge", par exemple, est plus grand que L. col BETWEEN x AND y n'est qu'un alias pour col >= x AND col <= y. Bref, si tu veux les mots qui commencent par les lettres J, K et L, tu dois faire un truc comme col >= 'J' AND col < 'M'.

      P.S. Utilise le forum Base de données la prochaine fois. Je déplace cette fois-ci.
      • Partager sur Facebook
      • Partager sur Twitter
        16 septembre 2011 à 23:32:05

        très bonne explication merci.

        Il reste cependant un problème avec la limite supérieur "Z" dans ce cas je met un truc genre "ZZZZZZ" et là ça devrais marcher non? ou bien il y a une autre solution?
        • Partager sur Facebook
        • Partager sur Twitter
          16 septembre 2011 à 23:54:46

          Tu peux alors omettre la condition "plus petit que" et faire quelque chose comme col >= 'Z'
          • Partager sur Facebook
          • Partager sur Twitter
            17 septembre 2011 à 9:36:40

            Utiliser un switch à la place de ta tripotée de elseif, ça permet aussi d'améliorer la lisibilité du code.
            • Partager sur Facebook
            • Partager sur Twitter
              17 septembre 2011 à 19:30:09

              Pour ne pas avoir à te poser la question des limites (et que se passe-t-il pour A et pour Z) et écrire une requête unique, tu peux appliquer tes conditions non pas sur le mot entier mais sur sa seule première lettre (puisque c'est elle qui t'intéresse - le tri étant lui appliqué au mot entier).
              L'utilisation de la clause BETWEEN au lieu des < et > redevient alors tout à fait indiquée.
              • Partager sur Facebook
              • Partager sur Twitter
                17 septembre 2011 à 20:33:57

                Je ne comprends pas ton intervention, Olb1604. BETWEEN ne peut pas fonctionner lorsqu'on veut avoir tous les mots qui commencent par la lettre A, B ou C parce que la condition col BETWEEN 'A' AND 'D' serait aussi vraie lorsque col vaut 'D'. Pas le choix d'utiliser l'opérateur <, donc.

                Dans tous les cas, on se base uniquement sur la première lettre, donc je comprends mal où tu veux en venir.
                • Partager sur Facebook
                • Partager sur Twitter
                  18 septembre 2011 à 11:06:23

                  $lim2 .= 'ZZZZZZZZZZZZZZZ';
                  


                  avant le 'prepare' et c'est bâclé.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    18 septembre 2011 à 19:34:39

                    Je veux en venir à cette requête où j'utilise la fonction SUBSTRING (en PostgreSQL mais je crois qu'elle existe aussi en MySQL et qu'il doit même y avoir une fonction LEFT mais on s'éloigne alors de la norme SQL) :

                    SELECT * FROM jeux 
                    WHERE plateforme = :console AND SUBSTRING(nom, 1, 1) BETWEEN :lim1 AND :lim2
                    ORDER BY nom ASC 
                    LIMIT :lim_aff_min,:nb_sujet_par_page
                    


                    @FAYDEN : je ne comprends pas ta remarque. Pour reprendre ton exemple, lorsqu'on veut avoir tous les mots qui commencent par la lettre A, B ou C j'utilise la condition BETWEEN 'A' AND 'C' et non pas BETWEEN 'A' AND 'D'...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 septembre 2011 à 19:50:41

                      Avec un between sur la 1ère lettre, je suis d'accord, sinon ça marche pas.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 septembre 2011 à 2:46:04

                        Citation : Olb1604

                        @FAYDEN : je ne comprends pas ta remarque. Pour reprendre ton exemple, lorsqu'on veut avoir tous les mots qui commencent par la lettre A, B ou C j'utilise la condition BETWEEN 'A' AND 'C' et non pas BETWEEN 'A' AND 'D'...


                        Non justement, c'est ce que j'explique depuis le début du topic :
                        fayden=> SELECT 'BANANE' BETWEEN 'A' AND 'C';
                         ?column? 
                        ----------
                         t
                        (1 ligne)
                        
                        fayden=> SELECT 'CHAT' BETWEEN 'A' AND 'C';
                         ?column? 
                        ----------
                         f
                        (1 ligne)

                        D'ailleurs, j'ai dit qu'il ne fallait pas utiliser BETWEEN pour ça parce que ça retournait quelque chose de faux. BETWEEN 'A' AND 'D' retourne toutes les chaînes commençant par A, B, C ET la chaîne 'D'.

                        Finalement, SUBSTRING fonctionne, certes, mais on ne peut pas utiliser d'index sous MySQL et il faut définir un index sur l'expression pour d'autres SGBDR. Aussi bien utiliser les opérateurs de comparaison >= et < qui font le même travail.
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Between et MSQL

                        × 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