PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#51 22-11-2011 12:16:33

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Pour les temps, j'avais bien vu que c'était en minutes, très bien.
j'ai tout passé en smallint comme tu avais dis il y a qq post.
Ma fonction me donnait des valeurs qui me convenait, genre au bout de 20 minutes un pet avait parcouru 18000. (donc ma formule fonctionne)
Par qq ajustement, c'était lié au nom des champs pour collé a mes tables (par exemple: power_min => puissance_min)

Voila un nouveau résultat de la requete :

id_course     id_pet     ellapsed     puissance_min      dist_parcourue      tps_restant                 
2     23     7.2500     5     0.03     12.7500
2     1     7.2500     5     0.02     12.7500
2     32     7.2500     5     -0.09     12.7500

DOnc puissance_min est bon, mais la distance parcouru non, et ca ne peut pas etre négatif


Je te colle aussi mes tables au cas ou et aussi pour voir ou j'en suis :


--
-- Structure de la table `course`
--

CREATE TABLE IF NOT EXISTS `course` (
  `id_course` int(11) NOT NULL auto_increment,
  `id_pseudo` int(11) NOT NULL,
  `depart_theorique` datetime NOT NULL,
  `depart` datetime default NULL,
  `duree` smallint(3) unsigned NOT NULL,
  `statut` tinyint(3) unsigned NOT NULL,
  `nom_circuit` varchar(20) NOT NULL,
  `level_min` tinyint(3) unsigned NOT NULL,
  `level_max` tinyint(3) unsigned NOT NULL,
  `ressource_type` tinyint(4) NOT NULL,
  `ressource_quantite` int(11) NOT NULL,
  `puissance_min` smallint(5) unsigned NOT NULL,
  PRIMARY KEY  (`id_course`),
  KEY `statut` (`statut`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Structure de la table `course_participant`
--

CREATE TABLE IF NOT EXISTS `course_participant` (
  `id_course` int(11) NOT NULL,
  `id_pet` int(11) NOT NULL,
  `id_pseudo` int(11) NOT NULL,
  PRIMARY KEY  (`id_course`,`id_pet`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


--
-- Structure de la table `pet`
--

CREATE TABLE IF NOT EXISTS `pet` (
  `id_pet` int(11) unsigned NOT NULL auto_increment,
  `nom_pet` varchar(40) NOT NULL,
  `id_pseudo` int(11) unsigned NOT NULL,
  `type_pet` tinyint(1) NOT NULL,
  `level` tinyint(3) unsigned NOT NULL,
  `xp` decimal(11,2) NOT NULL,
  `sante` smallint(6) unsigned NOT NULL,
  `strengh` smallint(3) unsigned NOT NULL,
  `resistance` smallint(3) unsigned NOT NULL,
  `endurance` smallint(3) unsigned NOT NULL,
  `reactivite` smallint(3) unsigned NOT NULL,
  `attaque` smallint(3) unsigned NOT NULL,
  `defense` smallint(3) unsigned NOT NULL,
  `agilite` smallint(3) unsigned NOT NULL,
  `portage` smallint(3) unsigned NOT NULL,
  `intelligence` smallint(3) unsigned NOT NULL,
  `vie` smallint(3) unsigned NOT NULL,
  `puissance` smallint(5) unsigned NOT NULL,
  `oqp` tinyint(1) NOT NULL,
  `aptitude` varchar(1) NOT NULL,
  `nourriture` varchar(1) NOT NULL,
  PRIMARY KEY  (`id_pet`),
  KEY `id_pseudo` (`id_pseudo`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=37 ;

 

Dernière modification par ebouilleur (22-11-2011 12:21:01)

Hors ligne

#52 22-11-2011 13:24:20

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bon,

Bien qu'il y ait encore des choses à dire sur la structure de tes tables (comme par ex la pertinence de id_pseudo), ton problème n'est pas là. Je vais aller donc à l'essentiel.

A mon avis le problème viens du fait que j'ai changé la précédence des opérateurs de ta fonction de calcul de distance.
Je m'explique.

Voici ton calcul PHP


 $puissance = $strong + $agilite + $intel;
  $distance_parcouru = ( $puissance - ($puissance_min/$endurance) * ($temps)/($duree * 20 * 60) ) * $temps ;
// Ici est soustrait à $puissance la valeur de ($temps*$puissance_min/$endurance)/$duree*120*$temps;
 

et voici le calcul mysql


  RETURN (((puissance-(puissance_min/endurance)*temps)/(duree*120))*temps)
<!-- Ici est calculé la valeur de (puissance_min/endurance) qui est soustraite à puissance. Ensuite on multiplie le résultat par temps et qu'on divise par duree*120. Ensuite on multiplie le résultat par temps. -->
 

Donc les deux calculs n'ont effectivement rien à voir. Si tu veux le même calcul en mysql remets dans ta fonction mysql les parenthèses comme elles le sont dans ta fonction PHP et ton problème sera résolu.

++

Dernière modification par Jc (22-11-2011 13:24:51)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#53 22-11-2011 16:11:07

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

OK,
Alors la procédure donne :


CREATE DEFINER=`root`@`localhost` FUNCTION `calc_dist`(endurance smallint, temps smallint, puissance_min smallint, puissance smallint, duree smallint) RETURNS decimal(6,2)
RETURN ((puissance-(puissance_min/endurance)*temps/(duree*120))*temps)
 

Et la résultat de la requete donne :

id_course     id_pet     ellapsed     dist_parcourue      tps_restant                 
2     1     11.0500     197.92     8.9500
2     23     11.0500     175.95     8.9500
2     32     11.0500     54.75     8.9500

Les distances ne sont pas identiques a ce que j'avais avant, mais comme ici tous les temps sont en secondes ça me semble normal. En tout cas les distances parcouru semblent logiques par rapport aux caractéristiques des pets!

Donc, me reste plus qu'a mettre ca en place et faire les crons pour le changement des status.

Pour stopper la course, tu penses que c'est mieux de faire comment? car faut l’arrêter a 20minutes pile (enfin si duree = 20)

En tout cas merci, ca m'a bien aider et j'ai appris plein de choses !

Et pour :

Jc a écrit :

Bien qu'il y ait encore des choses à dire sur la structure de tes tables (comme par ex la pertinence de id_pseudo), ton problème n'est pas là. Je vais aller donc à l'essentiel.

Pour le moment le id_pseudo n'est pas utile, mais apres j'espere intégrer la possibilité d'avoir plusieurs pet pour le meme joueur, donc j'en aurais peut etre besoin...

Dernière modification par ebouilleur (22-11-2011 16:13:09)

Hors ligne

#54 22-11-2011 18:07:50

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Concernant id_pseudo c'est ce qu'il m'avait semblé comprendre. Si c'est le cas tu en as besoin dans aucune des trois tables si tu veux bien faire les choses wink

Pour arrêter la course, je vois deux systèmes (le 2 est meilleur mais requiert le 1^^).
1) Via ta requête de gestion de courses.
Pour cela tu as besoin tout d'abord dans les caractéristiques de tes circuits (de courses) de renseigner la distance à parcourir. A partir de là, vu que la requête te renseignes sur la distance parcourue, suffit d'y rajouter un test avec une colonne "gagné" par exemple en BOOL au cas où le pet a parcouru la distance impartie avant la fin des 20minutes. Mais cela sera inexact.

2) Si ta course est de type déterministe
Ton serveur est le seul à connaître ta fonction de calcul de distance. Si 3 pets donnés parcourent toujours la même distance en un temps donné, ton serveur peut déterminer à l'avance (au moment du départ) qui va gagner la course et quand (à la seconde prêt) en fonction de la distance à parcourir. Si le fait de gérer cela via un timer via une console adm de gestion de course est facile, ca l'est moins de l'intégrer côté serveur en automatique. La solution serait de le faire une fois la course finie même si la détection de fin de course est faite à un instant t+x. Une fois détectée, le serveur calcule de la même manière qu'il est capable de le faire à l'avance les temps et distances parcourues du vainqueur et les enregistre dans la table de course qui contiendra à ce moment les valeurs exactes.

C'est une idée comme une autre wink

Dernière modification par Jc (22-11-2011 18:09:11)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#55 23-11-2011 11:00:26

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Désolé je pensais avoir répondu hier soir, mais j'ai du oublier hmm

Je ne vois pas trop comment faire pour savoir quelle est la distance a parcourir. C'est pour ca que j'avais décidé que la course serai gagné au bout de 20 minutes (car un pet niveau 1 et un autre niveau 30 ne vont pas parcourir la meme distance dans le meme temps. Surtout que pour le moment ma formule de calcule de distance est fixe, mais je dois l'améliorer pour donner un peu d'aléatoire (et aussi faire prendre en compte - je ne sais pas trop comment pr le moment - les différences entres les parcours - slalom, course de vitesse, etc)

Hors ligne

#56 23-11-2011 13:35:41

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Pour savoir quelle est la distance a parcourir, une simple colonne distance dans une table circuit ou dans la table course en attendant suffit.
Ensuite pour les différents types de parcours et pour te donner des idées, il faudrait définir un ensemble de points techniques avec leur quantité pour un parcours, sur lequels tu pourrais définir les caractéristiques minimum à avoir pour ne pas avoir de malus dans leur "négociation". Comme exemple de point techniques, "virage serré", montée, descente, endurance ( fatigue sur la longueur à courrir), enchainements de virages,... Comme exemple de critères pour "un virage serré" les critères determinant de base pourraient être la force puis l'agilité, etc... Ensuite à toi de construire un algorithme de calcul pour gérer tout cela..

++


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#57 23-11-2011 13:40:58

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Je suis ok sur le principe de rajouter une colonne distance, mais je la fabrique comment cette valeur "distance"?

Hors ligne

#58 23-11-2011 13:45:41

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Comme tu as envie dans un premier temps. Ensuite si tu appliques un système comme celui que je t'ai proposé, cela t'obligera sans doute à ne pas définir des distances trop longues pour les possibilités de pet, et d'introduire des niveaux de parcours en adéquation avec les niveaux des pets.


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#59 23-11-2011 14:15:09

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Ouais ok... mais justement, je n'arrivais pas a fixer de distance a parcourir pour gagné, c'est pour ca que j'ai utilisé la durée... donc je ne vois pas d'autre moment que de faire un cron qui vérifie le valeur depart (table course) et quand datetime > depart + 20 min alors on passe la course au statut 3
La j'ai passé ma matiné a mettre en place tout ce qu'on a dit et a faire mon cron pour passé la course au statut 1 (presque fini)... je vais voir pour le reste, continuer de réfléchir
merci

Hors ligne

#60 23-11-2011 16:17:33

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

En fait vu l'ampleur de la tâche c'est de savoir par où commencer. Si ma proposition de plaît, commence par définir tes définitions, c'est à dire, contraintes, minimums, bonus, malus, ce qu'ils apportents ou font perdre par unité de valeur et une fois fini, construit ta formule de calcul, et on s'en fou si elle est longue. A partir de là la capactité des pets à parcourir une distance donnée t'apparaîtra comme une évidence ou presque^^.


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#61 23-11-2011 16:36:39

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Oui elle me plait ta proposition, tu propose encore plus ce que j'avais pensé lol (car dans mon idée je pensais favoriser certes caractéristiques en fonction des parcours - c t plus simple ^^), et/mais comme tu dis c'est bcp de boulot...
Je pense que dans un 1er temps, je vais trouver un moment d'arreter la course sans connaitre de distance, mais je garde biensur tes remarques pour le futur

Sinon, j'essaye de récupéré la plus petite valeur de puissance dans la table pet (pour déterminer puissance_min de la course) mais j'y arrive pas hmm
Un petit coup de pouce stp?
Edit, c'est bon j'ai trouvé ca donne :


select MIN(puissance) as puissance_min
FROM pet
WHERE id_pet IN (SELECT id_pet FROM course_participant WHERE id_course='$id_course')
 

merci

Dernière modification par ebouilleur (23-11-2011 17:49:59)

Hors ligne

#62 23-11-2011 19:03:54

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bon, voila le cron qui clos les inscription des courses, et passe celle-ci au statut=1
(cron lancer 10 minutes avant le départ des courses - d'ailleurs je me demande si ma requete ligne 37 ne serai pas a améliorer pour rendre ne compte ses 10minutes...)


<?php
define (VERSION_ARGS, "-V");
/***************************************************************
* Recuperation des parametres
***************************************************************/

if ($argc > 1) {
   for($i=1;$i<=$argc;$i++) {
      $arg = substr($argv[$i],0,2);
      if (strcmp($arg,VERSION_ARGS) == 0) {
          list(,$version) = explode("=",$argv[$i],2);
      }  
   }
}

if ($version == "") {
   $version = $_GET['version'];  
}
// on regarde quel version du cron lancer
if ($version == "beta"){
  $chemin = "/home/ebouilleur/pet-racing/beta/";
} elseif ($version == "officiel") {
  $chemin = "/home/ebouilleur/pet-racing/www/";
} else {
  echo "<b>Bug, pas de version de sélectionné !!</b>";
  exit;
}

$today_simple = date("Y-m-d"); 
$today = date("Y-m-d G:i:s");  
$heure_depart  =  time() ;     

include ($chemin.'bdd/bdd_beta.php');
include ($chemin.'fonctions/course.php');  
include ($chemin.'fonctions/divers.php');  

/********************* On regarde si il y a des courses au départ ********************/
$select = "SELECT id_course, UNIX_TIMESTAMP(depart_theorique) as depart_theorique FROM course WHERE depart_theorique<=NOW() AND statut='0' ";  
//echo $select;
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {

  $id_course = $var_news['id_course'];
  $list_puissance = array();
 
  // on vérifie qu'il y a plus de 4 participants (sinon on annule la course)
  // a activer apres les test
  $sql = "SELECT id_pet, id_pseudo FROM course_participant WHERE id_course='$id_course' ";
  $req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
  if (mysql_num_rows($req) < 4){
    while ($vars_suppr=mysql_fetch_array($req)) {
    $id_pet_suppr = $vars_suppr['id_pet'];
    $id_pseudo = $vars_suppr['id_pseudo'];
    // la course est annulée
    // on supprime les participants
    $sqldel = "DELETE FROM course_participant WHERE id_pet='$id_pet_suppr' AND id_course = $id_course ";  
    mysql_query($sqldel) or die('Erreur SQL : effacement de sa participation !<br>'.$sqldel.'<br>'.mysql_error());     
 
    // on historise l'info
    $commentaire = "Annulation de la course par manque de participant.";
    send_sql("INSERT INTO course_histo VALUES ('$id_course','$id_pet_suppr','$id_pseudo_suppr','$commentaire','','$today') ","Historisation de l annulation de la course.");        
    }    
  $sqldel = "DELETE FROM course WHERE id_course='$id_course'";  
  mysql_query($sqldel) or die('Erreur SQL : effacement de la course sans participant !<br>'.$sqldel.'<br>'.mysql_error());  
  }
  //
  else
  // la course a bien lieu
  {
  // on cherche la valeur de puissance_min des participants de cette course
  $SQL2="select MIN(puissance) as puissance_min
        FROM pet
        WHERE id_pet IN (SELECT id_pet FROM course_participant WHERE id_course='$id_course')"
;
  $sel2 = mysql_query($SQL2) or die('Erreur SQL liste participants !<br>'.mysql_error());
  $var2=mysql_fetch_array($sel2);
  $puissance_min = $var2['puissance_min'];

  // on met les pet en oqp
  $sqlUp = "UPDATE pet
            SET oqp='4'
            WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course='2') "
;
  mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  

  // on passe la course au statut 1 (=course inscription close)  
  $sqlUp = "UPDATE course SET statut=1, puissance_min=$puissance_min WHERE id_course='$id_course'";
  mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
  }
}
echo "<b>Cloture des inscription aux courses réalisés</b>";

?>
 

Hors ligne

#63 23-11-2011 21:18:33

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonsoir,

Que tu te compliques la vie!

1) Déjà, il y a une imprécision au niveau des status si tu veux faire quelque chose de plus efficace, il faudrait faire ceci
0 : course ouverte au inscription
1 : cloture des inscriptions 10 min avant le départ Prêt à partir -> cron qui vérifie le nb de joueur
2 : course en cours
3 : course terminée
4: course archivée annulée
5: course archivée courrue

2) Imprécision :
- Tu gères le temps au niveau php pour ta tâche CRON c'est bien, mais ton fichier cron doit être appelé il me semble dans deux contexte différents : pour les inscriptions et pour les départs/clotures. Donc il faut que tu retrouves ces deux contextes dans ton fichier et c'est justement au niveau de ta gestion temps PHP que tu vas le vérifier.
- Ta requête ligne 37 n'est pas correcte et source d'erreur. il faudrait plutôt un truc basé sur ce critère (je te laisse le faire je vais t'en laisser un peu^^)


SELECT id_course FROM course WHERE UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP (NOW()) <=600 AND statut='0' ";

Et qu'elle ait la signature suivante : id_course, nb_participants. Ensuite tu pourrais aussi pour contourner les problèmes de verous monter les résultats dans une table de type memory pour pouvoir faire tes mises à jours en une seule requête.

3) Ne supprime pas les participants et sert toi du champs statuts pour archiver tes courses. Tu as donc juste un update à faire dessus. De plus ton DELETE ligne 55 n'a pas besoin d'être dans une boucle car un simple

DELETE FROM course_participant WHERE id_course = $id_course

est équivalent. L'intérêt de passer par le statut pour l'archiver est aussi que ton DELETE te générera ici une erreur dans un contexte INNODB car ta table course_participants se retrouverait avec des enregistrements orphelins...

4) Les lignes 49 à 64 sont donc inutiles

5) Les tâches à éxécuter dans ce contexte sont donc terminées : on passe le statut à 4 quand count(id_pet)<4 et on le passe à 1 sinon. Fin de la tâche cron dans le contexte inscriptions.

Voilà pour le moment.


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#64 23-11-2011 22:53:40

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Jc a écrit :

Bonsoir,

Que tu te compliques la vie!

On me le dis souvent ^^

Jc a écrit :

2) Imprécision :
- Tu gères le temps au niveau php pour ta tâche CRON c'est bien, mais ton fichier cron doit être appelé il me semble dans deux contexte différents : pour les inscriptions et pour les départs/clotures. Donc il faut que tu retrouves ces deux contextes dans ton fichier et c'est justement au niveau de ta gestion temps PHP que tu vas le vérifier.

Heu non, en fait je pensais faire un fichier cron par "étape", mais tu as surement raison, c'est mieux tout de le même.

Jc a écrit :

- Ta requête ligne 37 n'est pas correcte et source d'erreur. il faudrait plutôt un truc basé sur ce critère (je te laisse le faire je vais t'en laisser un peu^^)


SELECT id_course FROM course WHERE UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP (NOW()) <=600 AND statut='0' ";

Et qu'elle ait la signature suivante : id_course, nb_participants. Ensuite tu pourrais aussi pour contourner les problèmes de verous monter les résultats dans une table de type memory pour pouvoir faire tes mises à jours en une seule requête.

Oula autant j'ai "entendu parler" de table mémory dans la config de phpmyadmin, autant je ne sais pas comment ca marche, ni ce que c'est (meme si le nom est parlant)

Jc a écrit :

3) Ne supprime pas les participants et sert toi du champs statuts pour archiver tes courses. Tu as donc juste un update à faire dessus. De plus ton DELETE ligne 55 n'a pas besoin d'être dans une boucle car un simple

DELETE FROM course_participant WHERE id_course = $id_course

est équivalent. L'intérêt de passer par le statut pour l'archiver est aussi que ton DELETE te générera ici une erreur dans un contexte INNODB car ta table course_participants se retrouverait avec des enregistrements orphelins...

Oui t'as bien raison..
je pensais supprimer ce qui ne servait plus a rien de la table course et course_participant "pour y voir plus clair", mais autant garder tout là

Donc avec ce que je sais faire ca donne :


/*********************************
 * On regarde si il y a des courses au départ
 *  *********************************/

$select = "SELECT C.id_course, count(P.id_pet) AS nb_participants
           FROM course AS C
           LEFT JOIN course_participant AS P ON C.id_course=P.id_course
           WHERE (UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP(NOW())) <=600 AND statut='0'
           GROUP BY P.id_course "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
  $id_course = $var_news['id_course'];
  $nb_participants = $var_news['nb_participants'];
  // on vérifie qu'il y a plus de 4 participants (sinon on annule la course)
  if ($nb_participants < 4){
    $sqlUp = "UPDATE course SET statut=4 WHERE id_course='$id_course'";
    mysql_query($sqlUp) or die('Erreur SQL : maj statut annulation course !<br>'.$sqlUp.'<br>'.mysql_error());          
  }
  else
  // la course aura bien lieu
  {
    // on cherche la valeur de puissance_min des participants de cette course
    $SQL2="SELECT MIN(puissance) as puissance_min
           FROM pet
           WHERE id_pet IN (SELECT id_pet FROM course_participant WHERE id_course='$id_course')"
;
    $sel2 = mysql_query($SQL2) or die('Erreur SQL puissance_min !<br>'.mysql_error()); 
    $var2=mysql_fetch_array($sel2);
    $puissance_min = $var2['puissance_min'];
 
    // on met les pet en oqp
    $sqlUp = "UPDATE pet
              SET oqp='4'
              WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course='2') "
;
    mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  
 
    // on passe la course au statut 1 (=course inscription close)  
    $sqlUp = "UPDATE course SET statut=1, puissance_min=$puissance_min WHERE id_course='$id_course'";
    mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
  }
}
echo "<b>Cloture des inscription aux courses réalisés</b>";
 

Hors ligne

#65 23-11-2011 23:41:50

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Re,

C'est déjà beaucoup mieux, mais y a encore du taf^^
1)

ebouilleur a écrit :

en fait je pensais faire un fichier cron par "étape", mais tu as surement raison, c'est mieux tout de le même.

tu fais cela comme tu veux mais dans ton cas je reste convaincu que c'est en effet plus simple.
2) Une table memory c'est pas compliqué, en résumé c'est comme une table normale sauf qu'elle est gérée en mémoire plutôt que sur disque dur. C'est donc très rapide selon ce que tu souhaites faire ou selon tes contraintes de requêtage.
3) Vu que l'on est dans la partie des clôtures d'inscriptions, les lignes 29 à 33 n'ont rien à faire là car la course n'est pas encore lancée, sauf s'ils nont pas le droit d'aller pisser entre temps^^.
4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).
5) Pense toujours à optimiser un max des tâches CRON pour la raison qui vient d'être évoquée.. Ca pourrait t'éviter de mettre un jour un serveur à genoux.
6) Pour les autres requêtes je pense que tu peux passer de 3 requêtes à 2.
7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.
++

Dernière modification par Jc (23-11-2011 23:49:52)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#66 24-11-2011 15:50:18

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Jc a écrit :

2) Une table memory c'est pas compliqué, en résumé c'est comme une table normale sauf qu'elle est gérée en mémoire plutôt que sur disque dur. C'est donc très rapide selon ce que tu souhaites faire ou selon tes contraintes de requêtage.

Ok, mais je vois pas ou j'en aurais besoin...

Jc a écrit :

3) Vu que l'on est dans la partie des clôtures d'inscriptions, les lignes 29 à 33 n'ont rien à faire là car la course n'est pas encore lancée, sauf s'ils nont pas le droit d'aller pisser entre temps^^.

bah c'est un peu ca ^^ et en plus faudrait aussi vérifier s'il n'est pas occupé ailleurs et dans ce cas le supprimé de la liste des participants (et donc a faire avant le calcule du nombre de participant - eh oui le pet ne se limite pas a faire des courses, ils peut aussi aller combattre lol)

Jc a écrit :

4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).

bah j'ai besoin de connaitre puissance_min puis le mettre dans la table course.... non?

Jc a écrit :

5) Pense toujours à optimiser un max des tâches CRON pour la raison qui vient d'être évoquée.. Ca pourrait t'éviter de mettre un jour un serveur à genoux.
6) Pour les autres requêtes je pense que tu peux passer de 3 requêtes à 2.
7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.

Donc a priori, je ne pense pas réduire le nombre de requete.
Et je pensais appeler ce fichier toutes les 10 minutes (via crontab). Tu penses en plus que je dois faire un include de cette page quand un joueur va sur la page qui liste toutes les courses?
merci

Hors ligne

#67 24-11-2011 16:52:00

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour

ebouilleur a écrit :

bah j'ai besoin de connaitre puissance_min puis le mettre dans la table course.... non?

Réponse: Relis bien

ebouilleur a écrit :

Jc a écrit:

4) Ensuite pour information, lorsque tes circuits auront un niveau, ta puissance_min pourrait faire partie des critères requis pour accéder à la course et donc intervenir en plus du nombre de participants. Par contre ici, je n'en vois pas l'intérêt car la puissance min si elle est utilisée dans ton calcul de distance, elle est recalculée dynamiquement dans ta requête de gestion de course.. Tu peux donc supprimer je pense aussi les lignes 22 à 27 (la supprimer ici te fait économiser une requête serveur x la frequence d'interrogation de la tâche par jour sur le serveur).

Ok, mais je vois pas ou j'en aurais besoin...

: Pour réduire tes requêtes.

bah c'est un peu ca ^^ et en plus faudrait aussi vérifier s'il n'est pas occupé ailleurs et dans ce cas le supprimé de la liste des participants (et donc a faire avant le calcule du nombre de participant - eh oui le pet ne se limite pas a faire des courses, ils peut aussi aller combattre lol)

Il te faut donc refaire ta requête initiale (plus bonne).

Et je pensais appeler ce fichier toutes les 10 minutes (via crontab). Tu penses en plus que je dois faire un include de cette page quand un joueur va sur la page qui liste toutes les courses?

C'est bien mais cela n'est pas suffisant. Car ton serveur a besoin de savoir à l'execution ce qu'il doit faire : valider les courses ou lancer/cloturer les départs.

Donc a priori, je ne pense pas réduire le nombre de requete.

C'est pas obligatoire mais cela serait mieux^^.

++


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#68 24-11-2011 23:12:39

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Pour les tables memory, tu peux me donner un exemple concret de quand ca serai mieux pour moi d'en utiliser stp?

Sinon pour l'appel au fichier ailleur que dans le cron, j'arrive pas a en voir l'interet. Car les départs auront lieux à 10, 30 ou 50 minutes. Les clotures donc a 0, 20 ou 40minutes et les arrivées, 20 minutes apres les départs, soit 30, 50 et 10... donc un cron toutes les 10 minutes...
Car si j'appel mon fichier, genre include('cron_course.php'); dans ma page de récap de course ca va servir a rien de plus...
Enfin je ne saisi pas hmm

Et sinon voila ce que donne mon cron_course.php pour le moment :


/*********************************
 * On regarde si il y a des courses à mettre au statut 1 (soit Prêt à partir)
 *  *********************************/

$select = "SELECT C.id_course, count(P.id_pet) AS nb_participants
           FROM course AS C
           LEFT JOIN course_participant AS P ON C.id_course=P.id_course
           LEFT JOIN pet AS t1 ON t1.id_pet=P.id_pet
           WHERE t1.oqp=0 AND (UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP(NOW())) <=600 AND statut='0'
           GROUP BY P.id_course "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
  $id_course = $var_news['id_course'];
  $nb_participants = $var_news['nb_participants'];
  // on vérifie qu'il y a plus de 4 participants (sinon on annule la course)
  if ($nb_participants < 4){
    $sqlUp = "UPDATE course SET statut=4 WHERE id_course='$id_course'";
    mysql_query($sqlUp) or die('Erreur SQL : maj statut annulation course !<br>'.$sqlUp.'<br>'.mysql_error());          
  }
  else
  // la course aura bien lieu
  {
    // on cherche la valeur de puissance_min des participants de cette course
    /* pas besoin car fait dans la procédure stocké
    $SQL2="SELECT MIN(puissance) as puissance_min
           FROM pet
           WHERE id_pet IN (SELECT id_pet FROM course_participant WHERE id_course='$id_course')";
    $sel2 = mysql_query($SQL2) or die('Erreur SQL puissance_min !<br>'.mysql_error()); 
    $var2=mysql_fetch_array($sel2);
    $puissance_min = $var2['puissance_min'];
    */

    // on met les pet en oqp
    $sqlUp = "UPDATE pet
              SET oqp='4'
              WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course='2') "
;
    mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  
 
    // on passe la course au statut 1 (=course inscription close)  
    $sqlUp = "UPDATE course SET statut=1 WHERE id_course='$id_course'";
    mysql_query($sqlUp) or die('Erreur SQL : maj statut 1 course !<br>'.$sqlUp.'<br>'.mysql_error());
  }
}
echo "<b>Cloture des inscription aux courses réalisés</b>";


/*********************************
 * On regarde si il y a des courses à mettre au statut 2 (soit en course)
 *  *********************************/

$select = "SELECT id_course
           FROM course
           WHERE UNIX_TIMESTAMP(depart_theorique) >= UNIX_TIMESTAMP(NOW() AND statut='1' "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
  $id_course = $var_news['id_course'];
  // on passe la course au statut 2 (=course en cours)  
  $sqlUp = "UPDATE course SET statut=2, depart=NOW() WHERE id_course='$id_course'";
  mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
}
echo "<b>Course en cours...</b>";


/*********************************
 * On regarde si il y a des courses à mettre au statut 3 (soit course terminée)
 *  *********************************/

$select = "SELECT id_course, duree, ressource_type, ressource_quantite
           FROM course
           WHERE (UNIX_TIMESTAMP(depart_theorique)+duree*120) >= UNIX_TIMESTAMP(NOW() AND statut='2' "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
while ($var_news = mysql_fetch_array($result)) {
  $id_course = $var_news['id_course'];
  // on passe la course au statut 3 (=course fini)  
  $sqlUp = "UPDATE course SET statut=3 WHERE id_course='$id_course'";
  mysql_query($sqlUp) or die('Erreur SQL : maj départ course !<br>'.$sqlUp.'<br>'.mysql_error());
  // on calcule la distance parcouru par chaque pet
  $sql="SELECT t1.id_course,t1.id_pet,t5.ellapsed,calc_dist(t2.endurance,t5.ellapsed,t4.puissance_min,t2.puissance,t3.duree) as dist_parcourue,
      t3.duree-t5.ellapsed AS tps_restant, t2.nom_pet, t3.statut
      FROM course_participant AS t1
      LEFT JOIN pet AS t2 ON t1.id_pet=t2.id_pet
      LEFT JOIN course AS t3 ON t1.id_course=t3.id_course
      LEFT JOIN
        (SELECT t1.id_course AS courseid, t1.id_pet, MIN(t2.strengh+t2.agilite+t2.intelligence) as puissance_min
        FROM course_participant AS t1 left join pet as t2 on t1.id_pet=t2.id_pet GROUP BY t1.id_course) as t4 ON t1.id_course=t4.courseid  
      LEFT JOIN
        (SELECT id_course, ((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(depart)) /60) AS ellapsed FROM course) as t5 ON t1.id_course=t5.id_course
      WHERE t3.statut=2 AND t3.id_course=$id_course
      ORDER BY dist_parcourue DESC"
;  
  $result = mysql_query($sql)  or die ('Erreur selection des courses : '.mysql_error() );
  while ($var_news = mysql_fetch_array($result)) {
    $sqlUp = "UPDATE course_participant SET distance='".$var_news['dist_parcourue']."' WHERE id_course='$id_course' AND id_pet='".$id_pet."' ";
    mysql_query($sqlUp) or die('Erreur SQL : maj distance participants !<br>'.$sqlUp.'<br>'.mysql_error());  
  }
  // on reverse les ressources gagnées pour les 3 1er pet (respectivement 60% - 20% - 10% de toutes les ressources "misées")
  // a faire
  // on passe les pet en non oqp (a faire aussi)

}
echo "<b>Course en cours...</b>";
 

bonne nuit wink

Dernière modification par ebouilleur (25-11-2011 17:23:02)

Hors ligne

#69 25-11-2011 16:15:31

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

ebouilleur a écrit :

Pour les tables memory, tu peux me donner un exemple concret de quand ca serai mieux pour moi d'en utiliser stp?

L'exemple type puisque tu me le demandes c'est par exemple pour remplacer tes lignes 4 à 16 par seulement 4 requêtes. Tu me diras ca fait plus que ce qu'il y a déjà vu que j'en ai mis que deux!
Eh bien non, si tu comptes bien, et imaginons le cas d'une course avec 50 pets, tu auras : 1+50 requêtes dans ton exemple, et le but c'est d'optimiser en priorité tes tâches CRON.
Pour être concret, imaginons les deux requêtes suivantes simples


SELECT a,b,c,d from table1 where a=10;
UPDATE table1 SET b=15, c=10, d=1 WHERE a=10;
 

Si tu es sous INNODB et que tu souhaites transformer ces deux requêtes en une seule telles qu'elles, tu ne pourras pas (et sous MyISAM je te rassure, encore moins!) Pourquoi? Tout simplement car sur ton select ton moteur base de données vas poser un verrou en lecture (sur ta ligne en INNODB et sur ta table en MyISAM) qui t'empêchera de mettre à jour l'enregistrement en cours de lecture, alors que les deux requêtes séparées fonctionneront. Le but, pour contourner les verrous, est de créer une table de type MEMORY et de peupler ta table mémoire avec le résultat de ton select (en deux requêtes). Ainsi tu pourras mettre à jour ta table1 mais en lisant tes enregistrement à partir de table de type memory en une seule requête.

ebouilleur a écrit :

Sinon pour l'appel au fichier ailleur que dans le cron, j'arrive pas a en voir l'interet.

Tu m'as tout simplement mal compris, ou j'ai du mal m'exprimer.
Ton fichier cron actuel intègre 2 parties. La première vérifie les inscriptions et la 2e valide les départ/cloture des courses.
Actuellement si tu fais une tache cron toutes les 10minutes l'ensemble de ton fichier sera executé toutes les 10 minutes. Or la première partie n'a besoin que d'être éxécutée que 3 fois par heure et la 2e partie 3 fois par heure (au lieu de 6 fois par heure pour chaque partie actuellement). Il faut donc que tu intègres dans ce même fichier un test d'execution de chaque partie selon l'heure d'execution. C'est cela que je voulais t'expliquer en te disant

jc a écrit :

7) Te reste à créer la condition PHP dans ton fichier pour éxécuter ce bloc lorsque cela est nécessaire.

Pour le reste (la 2e partie) vu que c'est la première fois que tu me la montres, il y a autant de travail à faire dessus que ce que l'on vient de faire pour la 1ere partie. Et la je n'ai pas le temps, donc je reviens vers toi ce soir je pense.

Bonne journée.

Jc

Dernière modification par Jc (25-11-2011 18:04:25)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#70 25-11-2011 17:22:50

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

OK je pense que je vois l'idée pour les table memory.
Faut que je me documente pour savoir comment gérer ca

Pour le cron, ok je vois mieux, je m'en occupe dans la soirée

Et pour la 2eme partie, c'est nouveau car je l'ai codé a la suite (faut aussi que j'avance dans mon dev)... heureusement que tu ne vois pas tout le code mysql de mon site... j'imagine du coup que tu tomberais en dépression hmm

D'ailleurs le while (ligne 87 a 90) n'est jamais parcouru semble-t-il mais je ne comprend pas pourquoi sad

Merci

Dernière modification par ebouilleur (25-11-2011 17:42:50)

Hors ligne

#71 25-11-2011 17:53:03

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Re,

Un exemple d'une de mes tables de production d'un client de type memory


CREATE TABLE IF NOT EXISTS `m_valcopy` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `ft_id` int(10) unsigned NOT NULL,`is_ref` tinyint(1) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`), KEY `ft_id` (`ft_id`,`is_ref`))  
ENGINE=MEMORY AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
 

Au niveau declaration ce qui change se situe uniquement au niveau ENGINE, rien de plus^^.

Pour ta boucle il se peut que cela vienne de ton $id_course tu ne l'as pas mis entre simple quotes comme sur les précédentes. Encore un conseil c'est de faire un $id_course = intval($var_news['id_course']); dès le départ comme ça tu peux les retirer dans toutes tes requêtes, elles n'en seront que plus performantes.

Sinon c'est qu'elle ne te retourne aucun enregistrement, en cas je la relis à tête reposée tout à l'heure.
++

Dernière modification par Jc (25-11-2011 18:07:33)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#72 26-11-2011 00:01:18

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

OK je vais essayer d'en faire qqchose avec ces memory table wink demain matin ^^

Ma boucle, elle fonctionne.. c'est en effet qu'il n'y a pas d'enregistrement au statut 2, vu que juste avant je le passe au 3 sad

Sinon pour appeler les parties de mon cron au bon moment, je propose un truc simple :
J'appel via crontab mon fichier toutes les 10minutes et ensuite en fonction des minutes je lance la partie qui va bien


$minutes = date("m");
if ($minutes==0 OR $minutes==20 OR $minutes==40){$go_statut1 = TRUE}
// si $go_statut1 == TRUE alors on passe les course du statut 0 a 1
if ($minutes==10 OR $minutes==30 OR $minutes==50){$go_statut2 = TRUE AND $go_statut3 = TRUE}
// si $go_statut2 == TRUE alors on passe les course du statut 1 a 2
// si $go_statut3 == TRUE alors on passe les course du statut 2 a 3
 

ca va ou c'est trop simple?
Aller bonne nuit !
smile

Hors ligne

#73 26-11-2011 00:25:42

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Ton go_statut3, pour ce qu'il te sert^^ autant le retirer wink

Je sais plus si tu peux caler par exemple ton cron toutes les 10 minutes mais décalé de 10s. Si tu ne peux définir que par minute, je te propose de le faire à 1,11,21,31,41,51 sinon tu risques d'avoir des soucis avec ta tâche. A part tout ça, ça m'a l'air bien.^^

Bonne nuit wink


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#74 26-11-2011 12:48:31

ebouilleur
Membre
Lieu : Nantes
Inscription : 19-05-2009
Messages : 165
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Sisi je peux faire tout ce que je veux, je peux donc décaller mon cron de 10s. ca change qqchose dans mon truc de $minutes?

Sinon, j'ai essayer de faire la 1er partie de mon cron avec des memory table.
J'ai surement mal fait, car ca me fait plus de code ^^ tu vas me dire ce que tu en penses wink


/*********************************
 * On regarde si il y a des courses à mettre au statut 1 (soit Prêt à partir)
 *  *********************************/

$select = "SELECT C.id_course, P.id_pet, count(P.id_pet) AS nb_participants
           FROM course AS C
           LEFT JOIN course_participant AS P ON C.id_course=P.id_course
           LEFT JOIN pet AS t1 ON t1.id_pet=P.id_pet
           WHERE t1.oqp=0 AND (UNIX_TIMESTAMP(depart_theorique) - UNIX_TIMESTAMP(NOW())) <=600 AND statut='0'
           GROUP BY P.id_course "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );

// création de la table momery pour les nb_participant
$requete="
    CREATE TABLE IF NOT EXISTS `m_course_nb_participant` (
    `id_course` int(10) unsigned NOT NULL , `nb_participant` tinyint(4) unsigned NOT NULL, `statut` tinyint(4) unsigned NOT NULL,
     PRIMARY KEY (`id_course`))  
    ENGINE=MEMORY DEFAULT CHARSET=latin1
    "
;
$result = mysql_query($requete)  or die ('Erreur de création de la table memory du nb de participant : '.mysql_error() );

// création de la table momery pour les nb_participant
$requete="
    CREATE TABLE IF NOT EXISTS `m_course_oqp_pet` (
    `id_course` int(10) unsigned NOT NULL , `id_pet` int(10) unsigned NOT NULL , `oqp` tinyint(4) unsigned NOT NULL,
    PRIMARY KEY (`id_course`), KEY `id_pet` (`id_pet`))  
    ENGINE=MEMORY DEFAULT CHARSET=latin1
    "
;
$result = mysql_query($requete)  or die ('Erreur de création de la table memory du nb de participant : '.mysql_error() );

while ($var_news = mysql_fetch_array($result)) {
  $id_course = intval($var_news['id_course']);
  $nb_participants = $var_news['nb_participants'];
  $id_pet = intval($var_news['id_pet']);
 
  // on vérifie qu'il y a plus de 4 participants
  if ($nb_participants > 4){
    // on ajoute a la table m_course_nb_participant le statut des pet
    $oqp = 4;
    send_sql("INSERT INTO m_course_oqp_pet VALUES ('$id_course','$id_pet','$oqp') ","Enregistrement du statut des pets.");
     
    $sqlUp = "UPDATE pet
              SET oqp='4'
              WHERE id_pet in (SELECT C.id_pet FROM course_participant AS C WHERE C.id_course=$id_course) "
;
    mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  
    $statut = 1;
  }else{
    $statut = 4;
  }  
  // on ajoute a la table m_course_nb_participant le nb de participant
  send_sql("INSERT INTO m_course_nb_participant VALUES ('$id_course','$nb_participants','$statut') ","Enregistrement du nb de participant.");  
}

// on met a jour les courses en fct du nombre de participant
$sqlUp = "UPDATE course AS C, m_course_nb_participant AS MC
          SET C.statut=MC.statut
          WHERE C.id_course=MC.id_course "
;
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  


// on met a jour le statut du pet si il fait la course
$sqlUp = "UPDATE pet AS P, m_course_oqp_pet AS MP
          SET P.oqp=MP.oqp
          WHERE P.id_pet in (SELECT id_pet FROM m_course_oqp_pet) "
;
mysql_query($sqlUp) or die('Erreur SQL : maj oqp pet départ course !<br>'.$sqlUp.'<br>'.mysql_error());  


   
echo "<b>Cloture des inscription aux courses réalisés</b>";
 

Hors ligne

#75 26-11-2011 17:05:49

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Trier le résultat d'une requete puis l'afficher comme voulu

Bonjour,

Pour répondre à ta première question ca ne change rien à "ton truc de minutes" wink Ca change juste pour éviter les conflits de gestion. Donc 10s voire 5s c'est bien.

Alors excuses-moi mais ta première requête, que j'ai dû lire auparavant en diagonale n'est pas bonne non plus (normalement elle devrait ne pas fonctionner correctement si tu n'as pas d'erreurs, fais-moi un retour stp dessus).
Tu as changé la logique pour la résolution de ton cron, et ce n'est pas cela.

Ce qu'il faut faire en premier lieu c'est créer ta table de type memory (1 seule suffit) et d'y remonter toutes les informations que tu as besoin pour ton traitement.


CREATE TABLE IF NOT EXISTS `m_course` (
    id INT unsinged not null auto_increment, `id_course` int(10) unsigned NOT NULL , `id_pet` int(10) unsigned NOT NULL , `oqp` tinyint unsigned NOT NULL, status  tinyint unsigned NOT NULL, nbparticipants tinyint unsigned NOT NULL
    PRIMARY KEY (`id`), KEY idx_course (id_course), idx_pet (id_pet)  
    ENGINE=MEMORY DEFAULT CHARSET=latin1
 

Ensuite il te faut monter les informations dont tu as besoin dedans c'est à dire toutes les courses éligibles au prochain départ. A ce propos il faudra éviter d'y mettre le filtre WHERE opq=0 sinon tu risque de ne pas avoir toutes les courses. En effet, tu as choisi d'annuler les courses qui ont au moins un pet oqp au lieu d'exclure tout simplement le pet de la course préalablement au comptage des pets dispos au départ de la course.

Il te faut faire la requête suivante


INSERT INTO m_course (id_course, id_pet, oqp, statut, nbparticipants)
SELECT (C.id_course, P.id_pet, t1.oqp, C.statut, COUNT(P.id_pet) as nbparticipants
   FROM course AS C
   LEFT JOIN (SELECT id_course,id_pet FROM course_participant) AS P ON C.id_course=P.id_course
   LEFT JOIN (SELECT id_pet, oqp FROM pet) as t1 ON t1.id_pet=P.id_pet
   WHERE (UNIX_TIMESTAMP(depart_theorique)-UNIX_TIMESTAMP(NOW()))<=600 AND statut=0)
 

Maintenant tu as toutes les courses éligibles au départ avec l'ensemble des pets associés respectivement à chaque course (avec leur statut (course+pet)) dans ta table memory
Les données sont donc maintenant prêtes à être mises à jour.
Note1:Je vais prendre le cas de figure ou l'on exclue le pet oqp^^ ne m'en veut pas trop. Pour cela dans la définition de ta table course_participant, il faut rajouter le champ statut_pet en tinyint unsigned not null avec 1 en valeur par défaut par ex qui signinie "faisant partie de la course". On reserve la valeur 2=exclu pour la course (et tu peux virer id_pseudo il sert à rien dans cette table.
Note2: Comme au moment où j'ecris je ne me rappele pas de ta codification de statut de pet, j'utilise ici pour l'exemple 0=libre; 1=oqp, 


UPDATE course_participant,m_course
SET course_participant.statut_pet=2,m_course.nbparticipants=m_course.nbparticipants-1 WHERE course_participant.id_course=m_course.id_course AND course_participant.id_pet=m_course.id_pet AND m_course.oqp=1;

UPDATE course, pet, m_course
SET course.statut=1, pet.oqp=1 WHERE course.id_course=m_course.id_course AND pet.id_pet=m_course.pet_id AND MIN(m_course.nbparticipants)>=4
 

Alors pour le 2e update j'ai peur qu'en l'état cela ne passe pas et qu'il faille faire intervenir la table course_participant sur laquelle tu fais une jointure avec la table memory comme avec la première, et qu'ensuite que tu relies par une jointure avec la table course et pet.

L'idée est là.
Te reste encore une requête à faire pour annuler les courses qui n'ont pas au moins 4 pets au départ. Alors ca fera 5 (6 avec la suppression de la table memory à la fin) requêtes au lieu de 4, mais bon^^

++

Dernière modification par Jc (26-11-2011 17:36:31)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

Pied de page des forums