Requête me semblant compliquée

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Requête me semblant compliquée

par xfree » 26 juin 2007, 13:29

Je m'en suis sorti en faisant :

Code : Tout sélectionner

SELECT NumeroVelo FROM velos AS N WHERE NOT EXISTS ( SELECT 1 FROM velos AS P WHERE CateoriePtPassage IN ('BT', 'BS', 'BR') AND N.NumeroVelo = P.NumeroVelo ) GROUP BY NumeroVelo ;
Merci à tous,

XFree

par sadeq » 26 juin 2007, 11:19

Ô je pense que c'est juste un nuage qui passe. A mon avis il s'est trompé de bouton. :langue:

par zeus » 26 juin 2007, 10:36

Quelle est l'utilité de cette réponse ?
Je n'ai pas cherché à comprendre puisqu'il n'y a aucune explication mais j'ai l'impression que c'est de la nourriture à poubelle ...
Je laisse tout de même une chance à l'auteur de nous expliquer cette contribution

test

par test66 » 26 juin 2007, 10:31

function topvision($type) { 
      $querytop = $this->db_mysql("SELECT NBVISION, TITRE FROM PA_MEDIA WHERE TYPE='$type' ORDER BY NBVISION DESC LIMIT 0,10;"); 
      $reponses = ""; 
      $i = 1; 
      while($row = mysql_fetch_array($querytop, MYSQL_ASSOC)) { 
         $reponses .= $i . ') <span class="engras">'.$row['TITRE'].'</span> (<span class="enitalic">'.$row['NBVISION'].'</span> visions)<br />'; 
         $i = $i + 1; 
      } 
      return $reponses; 
   }

par AB » 26 juin 2007, 05:47

@Zeus
Oui et d'autant plus que dans le cadre du traitement php de mon exemple précédent, la création du tableau $parcour_ok n'est pas indispensable, auquel cas un if serait nécessaire pour afficher simplement
$query = "SELECT NumeroVelo, CategoriePtPassage FROM velos";
$result = mysql_query($query);

$parcour = array();

while ($row = mysql_fetch_assoc($result)){$parcour[$row['NumeroVelo']][] = $row['CategoriePtPassage'];}

mysql_free_result($result); 

foreach ($parcour as $numvelo => $index) 
      {  
     if (!in_array('BT', $parcour[$numvelo]) && !in_array('BR', $parcour[$numvelo]) && !in_array('BS', $parcour[$numvelo])) 
      echo $numvelo;
      } 
Ce code peut servir pour ceux qui n'ont pas la version mysql "dernier cri" sur leur serveur distant.

par zeus » 26 juin 2007, 00:42

côté performance, on doit être à des niveaux tellement insignifiant que je pense que c'est négligeable.

Je me trompe peut être, mais j'essaye toujours d'être d'abord lisible ;)

par AB » 26 juin 2007, 00:38

Niveau lisibilité je suis d'accord avec toi mais j'ai lu quelque part que les opérateurs ternaires étaient légèrement plus performants que les if. Alors j'ai l'habitude de les utiliser tant que cela ne deviens pas très compliqué à gérer. Peut-être une mauvaise habitude de ma part :?:

par zeus » 26 juin 2007, 00:30

Ce n'est que mon avis propre est c'est un peu HS, mais je trouve cette syntaxe difficilement lisible pour un test simple qui est seul dans une boucle :-k
(!in_array('BT', $parcour[$numvelo]) && !in_array('BR', $parcour[$numvelo]) && !in_array('BS', $parcour[$numvelo]))? $parcour_ok[] = $numvelo : '';
je trouve tout de même que cette syntaxe est plus lisible dans ce cas ;)
if ( !in_array('BT', $parcour[$numvelo]) && !in_array('BR', $parcour[$numvelo]) && !in_array('BS', $parcour[$numvelo]))
{
    $parcour_ok[] = $numvelo;
}

par AB » 26 juin 2007, 00:22

Pour ne pas avoir de répétition dans le résultat, je ferais plutôt :
$query = 'SELECT DISTINCT `NumeroVelo` FROM velos
WHERE `NumeroVelo` NOT IN
   (SELECT `NumeroVelo`
    FROM velos
    WHERE CategoriePtPassage = "BS"
               OR CategoriePtPassage = "BT"
               OR CategoriePtPassage = "BR")';
C'est nickel mais ce type de requête ne fonctionne pas encore sur de nombreux serveurs mutualisés.

Dans ce cas et si l'on veut n'effectuer qu'une seule requête, il reste la méthode du traitement php. Pour avoir le même résultat je faisais des trucs du genre:
$query = "SELECT NumeroVelo, CategoriePtPassage FROM velos";
$result = mysql_query($query);

$parcour = array();
$parcour_ok = array();

while ($row = mysql_fetch_assoc($result)){$parcour[$row['NumeroVelo']][] = $row['CategoriePtPassage'];}

mysql_free_result($result);

foreach ($parcour as $numvelo => $index) 
      {  
      (!in_array('BT', $parcour[$numvelo]) && !in_array('BR', $parcour[$numvelo]) && !in_array('BS', $parcour[$numvelo]))? $parcour_ok[] = $numvelo : '';
      }
	  
foreach ($parcour_ok as $numvelo)
     {echo $numvelo.'<br>';}
C'est là qu'on voit l'avantage des nouvelles techniques et de l'optimisation des requêtes :D

par sadeq » 25 juin 2007, 23:19

Désolé je n'avais pas bien compris la notion de parcours, dans ce cas tu fais comme a proposé Shrell à une nuance prés, lui il a fait une sélection par ID alors qu'il faut filtrer par "NumeroVelo"

Une requête composée, l'une extrait les parcours ayant au moins BS, BT ou BR et l'autre fait la soustraction (NOT IN) de cet ensemble de l'ensemble général:

Code : Tout sélectionner

SELECT * FROM vélos WHERE `NumeroVelo` NOT IN (SELECT DISTINCT `NumeroVelo` FROM vélos WHERE CategoriePtPassage = "BS" OR CategoriePtPassage = "BT" OR CategoriePtPassage = "BR")
Dans ton cas seul le vélo n° 103 répondra

par AB » 25 juin 2007, 22:40

Tu parlais tout à l'heure de Ptpassage, alors qu'en réalité tu pensais CategoriePtPassage.
Remplace alors PtPassage par CategoriePtPassage:

Code : Tout sélectionner

SELECT * FROM vélos WHERE CategoriePtPassage != 'BT' AND CategoriePtPassage != 'BS' AND CategoriePtPassage != 'BR'
ça n'ira pas mieux puisque la requête va retourner également le vélo 102 qui a fait au moins un passage sans BR BT ou BS

Je suis pas assez calé en mysql pour faire ça en une seule requête ni même pour savoir si c'est possible.
Pour ma part je ferais une requête puis un traitement php derrière.

par sadeq » 25 juin 2007, 19:32

Tu parlais tout à l'heure de Ptpassage, alors qu'en réalité tu pensais CategoriePtPassage.
Remplace alors PtPassage par CategoriePtPassage:

Code : Tout sélectionner

SELECT * FROM vélos WHERE CategoriePtPassage != 'BT' AND CategoriePtPassage != 'BS' AND CategoriePtPassage != 'BR'

par zeus » 25 juin 2007, 19:01

Modération :
Merci d'utiliser un titre clair et qui correspond bien à ta demande.
Les titres contenant "HELP", "Aidez-moi !" n'apportent rien à la compréhension de ton problème.
Par ailleurs, nous savons déjà par ton message que tu as besoin d'aide.

Tu peux corriger ton titre en éditant ton premier message.

Merci de prendre le temps de lire les règlements.

par xfree » 25 juin 2007, 18:40

Merci pour vos réponses mais elles ne répondent qu'en partie à mon problème.
En effet, je veux ressortir les vélos dont TOUS les Ptpassage sont différent de 'BT' 'BS' et 'BR'.

Extrait de ma table :
ID;NumeroVelo;PtPassage;CategoriePtPassage
1;102;12;'67'
2;102;14;'BT'
3;102;94;'BS'
4;102;98;'BT'
5;103;35;'45'
6;103;65;'78'
7;103;43;'89'

Dans cet extrait, j'aimerais construire la requête me permettant de ressortir le vélo ayant pour Numéro 103 puisque son parcours entier ne contient pas de PtPassage dont la catégorie est 'BT', 'BS' ou 'BR'.

Merci,

XFree

par Shrell » 25 juin 2007, 14:29

j'essaierais plutot ceci :

Code : Tout sélectionner

SELECT * FROM velos WHERE ID NOT IN (SELECT DISTINCT ID FROM velos WHERE PtPassage = "BS" OR PtPassage = "BT" OR PtPassage = "BR")
A voir si ta version de mysql supporte les subselect