Page 1 sur 2

Qu'est-ce quelle a cette requéte ?

Posté : 05 mai 2006, 10:12
par Kimble
Bonjour,
C'est le script des 2 listes déroulantes de Cyrano en php :
http://www.phpfrance.com/forums/voir_sujet-4562.php
Le but est de savoir combien de ventes 1 commercial a réalisé dans une année.
J'ai un probleme de tri sur la 2eme liste.
Table commercial :
id_commercial en auto
commercial

Table millesime :
id_millesime en auto
millesime

Table vente :
idmillesime
idcommercial

Tous les millesimes s'affichent dans la 2eme liste même quand le commercial n'a aucunes ventes !
Le probléme est certainement dans la requéte de la 2eme liste...je l'ai tourné dans tous les sens et pas mieux ! une idée ? merci.
case 'millesime_commercial':
include("connexion.php");?>
				<fieldset>
				<legend><strong>Ventes par commercial et par ann&eacute;e </strong></legend>
				<br />
				<table> 
				<tr>
<?php 
/* On récupère si elle existe la valeur du commercial envoyée par le formulaire */ 
/* On récupère si elle existe la valeur du millesime envoyée par le formulaire */  
				$com_choisi = isset($_POST['commercial'])?$_POST['commercial']:null; 
				$millesime_choisi = isset($_POST['millesime'])?$_POST['millesime']:null; 
				if(isset($_POST['ok']) && isset($_POST['millesime']) && $_POST['millesime'] && isset($_POST['commercial']) && $_POST['commercial'] != "") 
{ 				
} 
/*Création de la requete pour afficher les commerciaux*/
/*********************************************************************************/
{ 
				$sql1 = "SELECT DISTINCT `id_commercial`, `commercial`". 
					" FROM `commercial`". 
					" ORDER BY `commercial` ASC"; 
				$rech_commerciaux = mysql_query($sql1);
/* test du chemin de la requete mise en silence */
//echo $sql1;
				$code_commercial = array(); 
				$nom_commercial = array(); 
/* On active un compteur pour les commerciaux */ 
				$nb_commerciaux = 0; 
				if($rech_commerciaux != false) 
    { 
       			 while($ligne = mysql_fetch_assoc($rech_commerciaux)) 
        { 
            	array_push($code_commercial, $ligne['id_commercial']); 
        		array_push($nom_commercial, $ligne['commercial']); 
/* On incrémente le compteur sur les commerciaux */ 
            	$nb_commerciaux++; 
        } 
    } 
    ?> 
				<form action="<?php echo "#"; ?>" method="post" id="chgdept"> 
<?php 
				echo "<center>"; 
/*Liste déroulante des commerciaux*/
?>
				<td><select name="commercial" id="commercial" onchange="document.forms['chgdept'].submit();">
                  <option value="-1">- - - Choisissez un commercial - - -</option>
                  <?php 
    			for($i = 0; $i < $nb_commerciaux; $i++)  
    { 
?>
                  <option value="<?php echo($code_commercial[$i]); ?>"<?php echo((isset($com_choisi) && $com_choisi == $code_commercial[$i])?" selected=\"selected\"":null); ?>><?php echo($nom_commercial[$i]); ?></option>
                  <?php 
    } 
    ?>
                </select>
				  <?php 
   				mysql_free_result($rech_commerciaux); 
				
/*********************************************************************************/
/* On commence par vérifier si on a envoyé un numéro de commercial et le cas échéant s'il est différent de -1 */ 
    			if(isset($com_choisi) && $com_choisi != -1) 
    { 
/* Création de la requête pour avoir les millesimes de ce commercial */ 
				 $sql2 = "SELECT DISTINCT `millesime`,`id_millesime`,`idcommercial`". 
				" FROM `millesime`,`vente`". 
				" WHERE `idcommercial` = ". $com_choisi ."". 
				" GROUP BY `millesime` ASC"; 						
        { 
        		$rech_millesime = mysql_query($sql2);
/*Test d'affichage du chemin de la requete*/
//echo $sql2;
/* Un petit compteur pour les millesimes */ 
				$nd = 0; 
/* On crée 2 tableaux pour les millesimes */ 
				$code_millesime = array();
				$nom_millesime = array(); 
/* On va mettre les millesimes et id dans les deux tableaux */ 
				while($ligne_millesime = mysql_fetch_assoc($rech_millesime)) 
            { 
				array_push($code_millesime, $ligne_millesime['id_millesime']);
				array_push($nom_millesime, $ligne_millesime['millesime']); 
				$nd++;
            } 
/* Maintenant on peut construire la liste déroulante des millesimes*/ 
            ?> 
				<select name="millesime" id="millesime" onChange="document.forms['chgdept'].submit();"> 
           		<option value="-1">---Choisissez une année---</option> 
           <?php 
            	for($m = 0; $m<$nd; $m++) 
            { 
                ?> 
				
  				<option value="<?php echo($code_millesime[$m]); ?>"<?php echo((isset($millesime_choisi) && $millesime_choisi == $code_millesime[$m])?" selected=\"selected\"":null); ?>><center> Année <?php echo($nom_millesime[$m]); ?></center></option>                    
                <?php 
            } 
?> 
				</select> 
<?php 
        } 
/* Un petit coup de balai */ 
        		mysql_free_result($rech_millesime); 
    }     
/*********************************************************************************/  
				if(isset($com_choisi))
				if(isset($millesime_choisi))
    			 
    { ?>
        		<input type="button" name="ok" class="bouton" value="Envoyer" onClick="window.navigate('index.php?liste=recherche_millesime_commercial&choix=millesime_commercial&commercial=<?php echo $com_choisi; ?>&millesime=<?php echo $millesime_choisi; ?>')" >
   <? } ?>   				</td>  
				</form> 
<?php  
} ?>
				</tr>		  	
				</table>
				<br />
				</fieldset>		
<?php	

break;

Posté : 05 mai 2006, 10:26
par Cyrano
Salut,
au départ, ta structure de base est curieuse : qu'un vendeur puisse faire plusieurs ventes, c'est logique, mais est-ce qu'une vente peut être attribuée à plusieurs vendeurs ?

Posté : 05 mai 2006, 10:29
par Kimble
Salut Cyrano, non 1 vendeur a ses propres ventes...
J'ai déjà réalisé ton script avec 3 listes mais sur la même table et je n'ai eu aucun probléme !

Posté : 05 mai 2006, 10:34
par Kimble
Mais si je fais :
<?php
/* Création de la requête pour avoir les millesimes de ce commercial */ 
				 $sql2 = "SELECT DISTINCT `millesime`,`idmillesime`,`idcommercial`". 
				" FROM `millesime`,`vente`". 
				" WHERE `idcommercial` = ". $com_choisi ."". 
				" GROUP BY `idmillesime` ASC"; 						
        { 
        		$rech_millesime = mysql_query($sql2);
/*Test d'affichage du chemin de la requete*/
//echo $sql2;
/* Un petit compteur pour les millesimes */ 
				$nd = 0; 
/* On crée 2 tableaux pour les millesimes */ 
				$code_millesime = array();
				$nom_millesime = array(); 
/* On va mettre les millesimes et id dans les deux tableaux */ 
				while($ligne_millesime = mysql_fetch_assoc($rech_millesime)) 
            { 
				array_push($code_millesime, $ligne_millesime['idmillesime']);
				array_push($nom_millesime, $ligne_millesime['millesime']); 
				$nd++;
            } 
/* Maintenant on peut construire la liste déroulante des millesimes*/ 
            ?> 
				<select name="millesime" id="millesime" onChange="document.forms['chgdept'].submit();"> 
           		<option value="-1">---Choisissez une année---</option> 
           <?php 
            	for($m = 0; $m<$nd; $m++) 
            { 
                ?> 
				
  				<option value="<?php echo($code_millesime[$m]); ?>"<?php echo((isset($millesime_choisi) && $millesime_choisi == $code_millesime[$m])?" selected=\"selected\"":null); ?>><center> Année <?php echo($code_millesime[$m]); ?></center></option>   
<?php
Cela m'affiche dans la 2eme liste :
Année 1
Année 3
Année 6
Année 10
là le tri ce fait correctement.

Posté : 05 mai 2006, 10:34
par Cyrano
non 1 vendeur a ses propres ventes...
Je songeais à une table surnuméraire mais en fait c'est toi qui as raison : mais il manque un champ dans la table ventes : la date de la vente.

Posté : 05 mai 2006, 10:37
par Kimble
Ce qui est bizzard, c'est quand je clique sur le bouton Envoyer, je n'ai aucune erreur et mon tableau affiche bien les ventes du commercial avec le millesime choisi ! :?

Posté : 05 mai 2006, 10:45
par Kimble
mais il manque un champ dans la table ventes : la date de la vente.
C'est idmillesime
J'ai du louper une marche quelque part :oops:

Posté : 05 mai 2006, 11:07
par Cyrano
Bon, attends, que je comprenne bien : avec le terme de "millésime", j'ai des raisons de croire qu'il s'agit de vente de vin : un vin correspond à un millésime, on aura donc un 2003, un 1995 un 1998 etc.... mais ça ne veut pas obligatoirement dire qu'il sera vendu cette année là : le millésime et la date de la vente sont deux propriétés distinctes de ta table millésime et l'id_vendeur comme l'id_millesime sont des clés étrangères : je trouverais donc logique d'avoir le schéma suivant:

Code : Tout sélectionner

+------------------+ +--------------------+ +------------------+ | vendeur | | vente | | millesime | +------------------+ +--------------------+ +------------------+ | id_vendeur PK |------|id_vente PK |------| id_millesime PK | | nom_vendeur | |id_vendeur FK | | millesime | +------------------+ |id_millesime FK | +------------------+ |date_vente | +--------------------+
À partir de là, on peut imaginer une requête avec une jointure externe, un peu complexe mais qui reflèterait correctement ce que tu veux obtenir... faut que je fasse des tests et un petit jeu d'essai pour vérifier, mais la clé du fonctionnement de tes listes dépend de ça à mon avis.

Posté : 05 mai 2006, 11:19
par Kimble
1) Ceci n'a rien a voir avec le vin (ce qui serait plus agréable)
Ce sont des vendeurs de maisons.
2) Le but est de dire que le commercial Kimble=$com_choisi a vendu x maisons dans l'année par exemple 2005=$millesime_choisi
Structure des tables :

Code : Tout sélectionner

-- Structure de la table `commercial` -- CREATE TABLE `commercial` ( `id_commercial` int(11) NOT NULL auto_increment, `commercial` varchar(50) NOT NULL default '', PRIMARY KEY (`id_commercial`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Les commerciaux' AUTO_INCREMENT=10 ; -- Structure de la table `millesime` -- CREATE TABLE `millesime` ( `id_millesime` int(11) NOT NULL default '0', `millesime` varchar(50) NOT NULL default '', PRIMARY KEY (`id_millesime`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; -- Structure de la table `vente` -- CREATE TABLE `vente` ( `id_vente` int(11) NOT NULL auto_increment, `client` varchar(100) NOT NULL default '', `idsecteur` int(11) default NULL, `commune` varchar(50) default NULL, `date` varchar(50) default NULL, `idcategorie` int(11) default NULL, `adresse` blob, `idcommercial` int(11) default NULL, `idannexe` int(11) default NULL, `idfondation` int(11) default NULL, `idsol` int(11) default NULL, `idtoiture` int(11) default NULL, `idmillesime` int(11) default NULL, `idgeotechnicien` int(11) default NULL, `notes` text, `surface` varchar(150) default NULL, `profondeur` varchar(50) default NULL, PRIMARY KEY (`id_vente`), FULLTEXT KEY `client` (`client`), FULLTEXT KEY `commune` (`commune`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Détails des ventes' AUTO_INCREMENT=1333 ;

Posté : 05 mai 2006, 11:47
par Cyrano
Ok, on est bien d'accord et le schéma que j'ai suggéré correspond en fait parfaitement avec ta structure, a table vente comportant pas mal de champs supplémentaires qui pour l'heure ne nous intéressent pas, mais ceux dont on a besoin sont bien là.

Donc le problème, c'est maintenant la requête : la première liste correspond aux vendeurs, la seconde aux millésimes : tu dois donc pouvoir faire ressortir le nombre de vente d'un millésime donné même s'il est égal à 0 pour un vendeur donné.

Il va donc falloir passer par une requête comportant une jointure externe. L'exemple de mon tuto est basé sur le fait qu'aucune région n'a 0 département, la jointure externe ne se justifiait donc pas et une simple clause WHERE suffisait amplement.

Là, le cas est différent : utilises-tu la version 100% PHP ou la version JavaScript/PHP ?

Posté : 05 mai 2006, 12:21
par Kimble
utilises-tu la version 100% PHP ou la version JavaScript/PHP ?
100% php

Posté : 05 mai 2006, 13:19
par Cyrano
Ok, donc c'est la requête pour la réponse au rechargement qu'il faut : vite fait, on aura peut-être pas besoin de la jointure externe : sous toutes réserves et à tester:
$sql = "SELECT c.commercial, m.millesime, COUNT(v.id_vente) AS nombre_ventes ".
"FROM commercial AS c, ventes AS v, Millesime AS m ".
"WHERE c.id_commercial = ". $id_commercial ." ".
"  AND c.id_commercial = v.id_commercial ".
"  AND v.id_millesime = m.id_millesime ".
"  AND m.id_millesime = ". $id_millesime ." ".
"GROUP BY c.commercial, m.millesime;";

Posté : 05 mai 2006, 13:59
par Kimble
Ca me génére 2 erreurs de variables indéfinies :
Undefined variable: id_commercial
Undefined variable: id_millesime

Par contre j'ai fait ceci :
$sql2="SELECT DISTINCT m.millesime, m.id_millesime, v.idcommercial from vente v LEFT JOIN millesime m on m.id_millesime = v.idcommercial where idcommercial LIKE '%".$com_choisi."%' GROUP BY `id_millesime` ASC";
Je n'ai pas d'erreur mais rien ne s'affiche dans la liste, sauf :
Choississez une année
Année (ici rien)

Posté : 05 mai 2006, 18:09
par Cyrano
Ben c'est évident que si les variables ne sont pas initialisées, ça va causer une erreur. J'osais espérer que tu l'aurais vu quand même : initialise les avec les valeur du formulaire au rechargement.

Posté : 06 mai 2006, 09:36
par Kimble
Me revoilà aprés un probléme d'hydraulique dans la maison...
Voila la requéte qui marche au poil !
<?php
if(isset($com_choisi) && $com_choisi != -1) 
    { 				
				$sql2="SELECT DISTINCT  m.millesime, m.id_millesime, v.idmillesime, v.idcommercial from vente v LEFT JOIN millesime m on m.id_millesime = v.idmillesime where idcommercial LIKE '%".$com_choisi."%' GROUP BY `millesime` ASC";				 									
				$verif = mysql_query($sql2) or die("Erreur SQL, Oops ! la requéte n'est pas bonne !.");								
        { 
?>
J'avoue humblement que je n'ai pas du tout compris ta requéte...si tu pouvais me l'expliquer, histoire de me coucher (comme hier soir) moins bête ! merci.