Requête me semblant compliquée

Petit nouveau ! | 3 Messages

25 juin 2007, 13:20

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
Modifié en dernier par xfree le 26 juin 2007, 13:26, modifié 1 fois.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

25 juin 2007, 13:57

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'
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 377 Messages

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
Petit scarabée deviendra grand

Petit nouveau ! | 3 Messages

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

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

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.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

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'
Modifié en dernier par sadeq le 25 juin 2007, 22:54, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

ViPHP
AB
ViPHP | 5818 Messages

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.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

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
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

ViPHP
AB
ViPHP | 5818 Messages

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

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

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;
}
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
AB
ViPHP | 5818 Messages

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 :?:

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

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 ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
AB
ViPHP | 5818 Messages

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.

test66
Invité n'ayant pas de compte PHPfrance

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; 
   }

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

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
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer