Page 1 sur 2

Requête me semblant compliquée

Posté : 25 juin 2007, 13:20
par xfree
Bonjour,

Je débute en SQL, et j'ai un souci sur la requête.
J'ai une table qui représente le parcours d'un vélo, qui liste donc tous les points de passage d'un vélo.

ID
NumeroVelo
PtPassage
CateoriePtPassage


J'aimerais ressortir tous les vélos dont TOUS les Ptpassage sont différent de 'BT' 'BS' et 'BR'.

Je suis parti sur l'idée qu'il faut pour chaque vélo:
- Compter le nombre de passage dans son parcours
- Compter le nombre de passage dont le PtPassage sont différents de 'BT', 'BS' et 'BR'

Si les 2 compteurs sont égaux, alors son parcours correspond à ce que je cherche.

Avez vous une petite idée ?

Par avance merci,

XFree

Version SGBD : Oracle9i

Re: Help requête SQL

Posté : 25 juin 2007, 13:57
par sadeq
J'aimerais ressortir tous les vélos dont TOUS les Ptpassage sont différent de 'BT' 'BS' et 'BR'.
Ta table "vélos" est:
  • ID
    NumeroVelo
    PtPassage
    CateoriePtPassage
Pseudo SQL: Extraire toutes les infos sur les vélos telque Ptpassage est différent de 'BT', 'BS' et 'BR'
SQL: SELECT * FROM vélos WHERE Ptpassage != 'BT' AND Ptpassage != 'BS' AND Ptpassage != 'BR'

Posté : 25 juin 2007, 14:29
par Shrell
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

Posté : 25 juin 2007, 18:40
par xfree
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

Posté : 25 juin 2007, 19:01
par zeus
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.

Posté : 25 juin 2007, 19:32
par sadeq
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'

Posté : 25 juin 2007, 22:40
par AB
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.

Posté : 25 juin 2007, 23:19
par sadeq
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

Posté : 26 juin 2007, 00:22
par AB
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

Posté : 26 juin 2007, 00:30
par zeus
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;
}

Posté : 26 juin 2007, 00:38
par AB
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 :?:

Posté : 26 juin 2007, 00:42
par zeus
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 ;)

Posté : 26 juin 2007, 05:47
par AB
@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.

test

Posté : 26 juin 2007, 10:31
par test66
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; 
   }

Posté : 26 juin 2007, 10:36
par zeus
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