PHP|Débutant :: Forums

Advertisement

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

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

#76 27-11-2011 10:58:58

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,

Avec un peu de recul, je pense qu'il serait plus opportun dans mon exemple de sortir les pets de la course avant de monter les infos dans ta table memory. Tes UPDATE en seront plus stables et plus efficaces en termes de performances. Ainsi le nombre de participants dans ta table memory seraient les bons.

Donc la première requête serait
(Cet update va t'exclure tous les pets oqp de toutes les courses éligibles pour le prochain départ.)


UPDATE course_participant,pet,course
SET course_participant.statut_pet=2
WHERE course_participant.id_course=course.id_course AND course_participant.id_pet=pet.id_pet AND course.statut=0 AND pet.oqp=1 AND UNIX_TIMESTAMP(course.depart_theorique)-UNIX_TIMESTAMP(NOW()))<=600
 

Ensuite tu crées ta table MEMORY et tu remontes les infos dedans comme precedemment (en rajoutant un filtre dans lequel course_participant.statut_pet=1)

Pour la mise à jour cela modifie les choses
-Le premier update n'est plus necessaire
- En ce qui concerne le second il devient


UPDATE course,pet,m_course
SET course.statut=1, pet.oqp=1 WHERE course.id=m.course.id_course AND pet.id_pet=m_course.pet_id AND m_course.nbparticipants>=4
 

La dernière pour archiver les courses qui n'ont pas assez de pets au départ: (course.statut=3 => course annulée : désolé je m'y perds avec tes statuts^^)


UPDATE course,pet,m_course
SET course.statut=3 WHERE course.id=m.course.id_course AND pet.id_pet=m_course.pet_id AND m_course.nbparticipants<4
 

N'oublie pas d'indexer tous tes champs statut dans tes tables.

PS: Les requêtes dans ce post ont été testées. Il faudrait test les différences de performances en créant une clé primaire composite (comme pour course_participant) sur m_course par rapport à l'actuelle.
EDIT: Le dernier update implique une certaine redondance dans le traitement qui devrait pouvoir s'optimiser.

Bon dimanche.

Dernière modification par Jc (27-11-2011 13:36:29)


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

Hors ligne

#77 27-11-2011 11:52: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

Salut

J'ai lu tres vite fait, mais :

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.

J'ai du mal codé, car je veux justement exclure le pet qui est oqp..

Hors ligne

#78 27-11-2011 13:37:02

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 tant mieux, j'ai deviné malgrès tout ce que tu voulais faire wink


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

Hors ligne

#79 27-11-2011 20:45:34

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,

Pour la 2e partie de ton CRON, voici quel devrait être l'algorithme.
A) On commence par clôturer les courses en cours qui sont terminées.
1) Pour chaque course et donc pour chaque circuit on calcule l'ordre et le temps d'arrivée de chaque pet de la course (d'abord sur la distance puis sur le temps).
2) On met à jour les courses avec ces valeurs exactes calculées pour les valeurs définitives
3) On attribue les récompenses s'il y en a (difficile de le faire après, même si c'est mieux pour alléger le cron mais cela oblige à le faire hors automatisation.
4) On cloture les courses ci-dessus.
B) On lance le départ des courses en attente.
5) On met à jour le statut des courses au départ. 
6) Fin.

++

Dernière modification par Jc (27-11-2011 20:47:17)


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

Hors ligne

#80 28-11-2011 14:28:28

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

Salut;
je reviens sur ton dernier post de la page 3 :

Jc a écrit :

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
 

J'ai un soucis sur la création de la table m_course.
Pourquoi dans les key tu met idx_course?


requête SQL:

CREATE TABLE IF NOT EXISTS `m_course` (
`id` INT( 10 ) unsigned NOT NULL AUTO_INCREMENT ,
`id_course` int( 10 ) unsigned NOT NULL ,
`id_pet` int( 10 ) unsigned NOT NULL ,
`oqp` tinyint unsigned NOT NULL ,
`statut` 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

MySQL a répondu:Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(`id`), KEY idx_course (id_course), idx_pet (id_pet)  
        ) ENGINE=MEMORY ' at line 3

Et donc en principe pour la totalité de cette partie ca donne :


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

// on met a jours les pet qui ne pourront pas participer
$select = "UPDATE course_participant,pet,course
    SET course_participant.statut_pet=2
    WHERE course_participant.id_course=course.id_course AND course_participant.id_pet=pet.id_pet AND course.statut=0 AND pet.oqp!=0 AND UNIX_TIMESTAMP(course.depart_theorique)-UNIX_TIMESTAMP(NOW()))<=600
 "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
 // création de la table memory course
$requete="
        CREATE TABLE IF NOT EXISTS `m_course` (`id` INT(10) unsigned not null auto_increment, `id_course` int(10) unsigned NOT NULL , `id_pet` int(10) unsigned NOT NULL , `oqp` tinyint unsigned NOT NULL, `statut`  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
    "
;
$result = mysql_query($requete)  or die ('Erreur de création de la table memory course : '.mysql_error() );
// on remplit la table m_course de toutes les infos
$select = "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 AND course_participant.statut_pet=1)
 "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );

// on met a jour le statut oqp du pet a 4 et on cloture les inscriptions de la course si il y a plus de 4 pet
$sqlUp = "UPDATE course,pet,m_course
          SET course.statut=1, pet.oqp=1
          WHERE course.id=m.course.id_course AND pet.id_pet=m_course.pet_id AND m_course.nbparticipants>4
 "
;
mysql_query($sqlUp) or die('Erreur SQL : maj course, pet, m_course !<br>'.$sqlUp.'<br>'.mysql_error());  
// on met a jour le statut oqp du pet a 0 et on annule la course si il y a moins de 4 pet
$sqlUp = "UPDATE course, pet, m_course
          SET course.statut=4
          WHERE course.id_course=m_course.id_course AND pet.id_pet=m_course.pet_id AND m_course.nbparticipants<=4 "
;
mysql_query($sqlUp) or die('Erreur SQL : maj course, pet, m_course !<br>'.$sqlUp.'<br>'.mysql_error());  
// on efface la table m_course
$sqlDel = "DROP TABLE m_course ";
mysql_query($sqlDel) or die('Erreur SQL : delete m_course !<br>'.$sqlDel.'<br>'.mysql_error());  

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

 

Dernière modification par ebouilleur (28-11-2011 14:43:47)

Hors ligne

#81 28-11-2011 15:34:53

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

Alors rappel pour les différents status :

Statuts des Courses :
0 : course ouverte aux inscriptions
1 : clôture 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 courue

Occupation des pet ($oqp) :
0 : libre
1 : dans le coma
2 : oqp a faire du commerce
3 : oqp au combat
4 : oqp en course

Jc a écrit :

Bonsoir,

Pour la 2e partie de ton CRON, voici quel devrait être l'algorithme.
A) On commence par clôturer les courses en cours qui sont terminées.
1) Pour chaque course et donc pour chaque circuit on calcule l'ordre et le temps d'arrivée de chaque pet de la course (d'abord sur la distance puis sur le temps).
2) On met à jour les courses avec ces valeurs exactes calculées pour les valeurs définitives
3) On attribue les récompenses s'il y en a (difficile de le faire après, même si c'est mieux pour alléger le cron mais cela oblige à le faire hors automatisation.
4) On clôture les courses ci-dessus.
B) On lance le départ des courses en attente.
5) On met à jour le statut des courses au départ. 
6) Fin.

++

Je dois aussi créé un table memory pour ta partie A je suppose?

Hors ligne

#82 28-11-2011 16:48:55

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

Voici la table m_course corrigée


CREATE TABLE `m_course` (
  `id` int(10) unsigned NOT NULL,
  `id_course` int(10) unsigned NOT NULL,
  `id_pet` int(10) unsigned NOT NULL,
  `oqp` tinyint(3) unsigned NOT NULL,
  `status` tinyint(3) unsigned NOT NULL,
  `nbparticipants` tinyint(3) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_course` (`id_course`),
  KEY `idx_pet` (`id_pet`),
  KEY `idx_status` (`status`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
 

Pour répondre à ta question c'est plus facile de préfixer le nom d'un index par idx pour savoir ce qu'il représente quand on code et de plus c'est le nommage interne naturel des SGBDRs.

Ton commentaire ligne 33 est inéxact car la requête ne touche pas au statut du pet. (normal).

Ensuite pour répondre à ta dernière question, à savoir si tu auras besoin d'une table de type memory pour la partie B, la réponse est non, je ne pense pas à ce stade (mais peut être^^).

Si tu veux optimiser le tout, (c'est déjà très bien comme c'est, ce que je te dis là c'est pour informations) faut mettre tout cela en INNODB en transactionnel (pour la partie que tu m'as montrée dans ton dernier post le code est déjà opti pour cela manque juste les définitions des foreign keys), et l'étape suivante est de mettre ce process dans une procédure stockée^^.

++

Dernière modification par Jc (28-11-2011 17:12:52)


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

Hors ligne

#83 28-11-2011 18:19:27

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 :

Ton commentaire ligne 33 est inéxact car la requête ne touche pas au statut du pet. (normal).

Heu exacte, je pense que j'ai laissé le commentaire tel quel alors que j'avais modifié la requete

Jc a écrit :

Ensuite pour répondre à ta dernière question, à savoir si tu auras besoin d'une table de type memory pour la partie B, la réponse est non, je ne pense pas à ce stade (mais peut être^^).

Ma question était pour A wink

Jc a écrit :

Si tu veux optimiser le tout, (c'est déjà très bien comme c'est, ce que je te dis là c'est pour informations) faut mettre tout cela en INNODB en transactionnel (pour la partie que tu m'as montrée dans ton dernier post le code est déjà opti pour cela manque juste les définitions des foreign keys), et l'étape suivante est de mettre ce process dans une procédure stockée^^.

++

Mouais, j'ai deja été loin je trouve dans ce qu'on a fait ensemble en qq jours wink mais si mon jeux tourne aussi bien que Ogame, je crois que ca sera necessaire ^^

J'essaye de te poster mon cron complet demain wink
merci

Hors ligne

#84 29-11-2011 14:12: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

Salut,

Jc a écrit :

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)
 

Il doit y avoir une erreur dans ta requete.
Si j'enleve les () du SELECT ca semble aller mieux.. mais il dit quand meme : #1054 - Unknown column 'course_participant.statut_pet' in 'where clause'  Alors que j'ai bien créé statut_pet

Dernière modification par ebouilleur (29-11-2011 14:21:28)

Hors ligne

#85 29-11-2011 21:06:32

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,

Il doit y avoir erreur sur la requête concernée car la colonne course_participant.statut_pet n'intervient nulle part dans cette requête.
Le "AND statut=0" concerne le statut course et par conséquent la colonne C.statut, le statut du pet dans cette requête est représenté par la colonne oqp et donc t1.oqp.

Tu m'inquiètes un peu sur la compréhension de la requête car si tu as remplacé statut=0 par statut_pet c'est normal qu'il y ait une erreur..

++

Dernière modification par Jc (29-11-2011 21:08:55)


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

Hors ligne

#86 29-11-2011 22:17:30

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

Heu en fait je comprenais pas pourquoi j'avais ca dans mon code...
J'ai mal interprété ta phrase (de ton  1er post de la page 4) :

Ensuite tu crées ta table MEMORY et tu remontes les infos dedans comme precedemment (en rajoutant un filtre dans lequel course_participant.statut_pet=1)

Ca serai plutot qqchose comme ca :


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 WHERE statut_pet=1) 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 GROUP BY C.id_course
 

Et si c'est bien ca, il y a qqchose qui me dérange, c'est que ca ne crée que 1 enregistrement dans la table.. ca devrait en faire autant qu'il y a de pet non?
Donc un oubli/erreur sur mon code un peu plus haut?


Sinon, pour la création de la table m_course, id ne devrait pas être en auto incrément?

Merci pour ta patience wink

Dernière modification par ebouilleur (29-11-2011 23:03:02)

Hors ligne

#87 30-11-2011 01:49: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

Bonsoir,

Si tu as raison l'id de la table m_course doit être en auto_increment et c'est la raison pour laquelle un seul enregistrement est créé. Donc le group by tu peux l'enlever normalement.
La raison de cette erreur, c'est qu'initialement j'avais crée à tord une clé primaire composite sur m_course (même structure que course_participant) mais cela impacte trop les performances des UPDATE, raison pour laquelle j'ai modifié le code en oubliant visiblement l'auto incrément qui me semblait avoir mis car je me souviens d'y avoir pensé.

++


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

Hors ligne

#88 30-11-2011 11:58:35

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 je l'avais mis (post précédent celui que tu as relevé) et juste oublié de le remettre...


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

Hors ligne

#89 30-11-2011 16:20: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

Jc a écrit :

Bonsoir,

Si tu as raison l'id de la table m_course doit être en auto_increment et c'est la raison pour laquelle un seul enregistrement est créé. Donc le group by tu peux l'enlever normalement.
La raison de cette erreur, c'est qu'initialement j'avais crée à tord une clé primaire composite sur m_course (même structure que course_participant) mais cela impacte trop les performances des UPDATE, raison pour laquelle j'ai modifié le code en oubliant visiblement l'auto incrément qui me semblait avoir mis car je me souviens d'y avoir pensé.

++

Ok,
par contre elle sert a quoi la colonne id_pet? car elle ne stock l'id de qu'un seul pet... c'est bizarre ca non?

Hors ligne

#90 30-11-2011 18:54:12

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

Oh! mille excuses, j'ai inversé les tables...

Ca doit donner ceci


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

J'ai pas le temps de test pour le count, mais regarde si tu enlèves l'auto equijointure si le count ne modifie pas les résultats. Si c'est le cas, supprime donc le premier left join et fait le count sur CP.id_pet.

++

Dernière modification par Jc (30-11-2011 18:54:31)


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

Hors ligne

#91 01-12-2011 17:34:49

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

Salut
En faisant :


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

j'ai l'erreur : #1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

Si je rajouter un  GROUP BY CP.id_pet après statut=0 ca fonctionne et ca me crée bien 4 enregistrement dans ma table :

id     id_course     id_pet     oqp     statut     nbparticipants
1    7    1    0    0    4
2    7    21    0    0    4
3    7    23    0    0    4
4    7    32    0    0    4

Du coup, je pense que c'est pas mal non?
smile

Dernière modification par ebouilleur (01-12-2011 17:37:13)

Hors ligne

#92 01-12-2011 22:28:11

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,

Oui tout à fait wink


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

Hors ligne

#93 02-12-2011 23:57:57

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, bon la partie 1 du cron est completement fonctionnel (tester et approuvé par mes soins wink )


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

// on met a jours les pet qui ne pourront pas participer
$select = "UPDATE course_participant,pet,course
    SET course_participant.statut_pet=2
    WHERE course_participant.id_course=course.id_course AND course_participant.id_pet=pet.id_pet AND course.statut=0 AND pet.oqp!=0 AND UNIX_TIMESTAMP(course.depart_theorique)-UNIX_TIMESTAMP(NOW()))<=600 "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );
 // création de la table memory course
$requete="CREATE TABLE `m_course` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `id_course` int(10) unsigned NOT NULL,
      `id_pet` int(10) unsigned NOT NULL,
      `oqp` tinyint(3) unsigned NOT NULL,
      `statut` tinyint(3) unsigned NOT NULL,
      `nbparticipants` tinyint(3) unsigned NOT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_course` (`id_course`),
      KEY `idx_pet` (`id_pet`),
      KEY `idx_statut` (`statut`)
    ) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci"
;
$result = mysql_query($requete)  or die ('Erreur de création de la table memory course : '.mysql_error() );
// on remplit la table m_course de toutes les infos
$select = "INSERT INTO m_course (id_course, id_pet, oqp, statut, nbparticipants)
     SELECT CP.id_course, CP.id_pet, t1.oqp, C.statut, COUNT(P.id_pet) as nbparticipants
     FROM course_participant AS CP
     LEFT JOIN (SELECT id_course,id_pet FROM course_participant) AS P ON CP.id_course=P.id_course
     LEFT JOIN (SELECT id_pet, oqp FROM pet) as t1 ON t1.id_pet=CP.id_pet
     LEFT JOIN course AS C ON CP.id_course=C.id_course
     WHERE (UNIX_TIMESTAMP(depart_theorique)-UNIX_TIMESTAMP(NOW()))<=600 AND statut=0 GROUP BY CP.id_pet "
;  
$result = mysql_query($select)  or die ('Erreur selection des courses : '.mysql_error() );

// on met a jour le statut oqp du pet a 4 et on cloture les inscriptions de la course si il y a plus de 4 pet
$sqlUp = "UPDATE course,pet,m_course
          SET course.statut=1, pet.oqp=4
          WHERE course.id_course=m_course.id_course AND pet.id_pet=m_course.id_pet AND m_course.nbparticipants>4 "
;
mysql_query($sqlUp) or die('Erreur SQL : maj course, pet, m_course !<br>'.$sqlUp.'<br>'.mysql_error());  
// on met a jour le statut de la course si il y a moins de 4 pet
$sqlUp = "UPDATE course, pet, m_course
          SET course.statut=4
          WHERE course.id_course=m_course.id_course AND pet.id_pet=m_course.id_pet AND m_course.nbparticipants<=4 "
;
mysql_query($sqlUp) or die('Erreur SQL : maj course, pet, m_course !<br>'.$sqlUp.'<br>'.mysql_error());  
// on efface la table m_course
$sqlDel = "DROP TABLE m_course ";
mysql_query($sqlDel) or die('Erreur SQL : delete m_course !<br>'.$sqlDel.'<br>'.mysql_error());  

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

Sinon, je me posais une question.
Quand, a la fin du course, je dois attribuer les gains aux gagnant, je redistribue 90% des ressources investi... j'ai donc besoin de savoir le nombre de participant. Ne serait il donc pas judicieux de stoquer ce nombre dans la table course (au lieu de recalculer vu qu'on l'a deja calculé dans la partie 1)?

Hors ligne

#94 03-12-2011 01:07:15

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,

C'est déjà largement mieux qu'au début!!! big_smile
Il y a encore un truc qui m'embête (même dans un contexte non transactionnel) et qui n'est pas beau à voir ce sont tes "or die()" .... Mais bon..

Pour ta question c'est une possibilité tout à fait cohérente, donc oui.

Félicitations en tout cas. Ta première impression sur le résultat obtenu? Si tu as gardé le code initial je t'invite à comparer les performances wink

Bonne nuit.

Dernière modification par Jc (03-12-2011 01:08:30)


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

Hors ligne

#95 03-12-2011 12:09: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

Oui j'avoue, il y a bcp moins de requete que mon code initiale ^^
Par contre y a une méthode simple pour comparer les performance? ou faut tout mettre dans une page et calculé le temps de chargement de la page?

Et sinon, c'est que que tu n'aime pas avec mes "die ()"

Hors ligne

#96 03-12-2011 12:34:55

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 mesurer les perfs d'un script plusieurs méthodes, voici une piste

Sinon pour tes die(), prends l'habitude de travailler avec un gestionnaire d'erreur.
Tout comme on viens de faire avec MySQL, la première étape avant d'intégrer un véritable gestionnaire d'erreur serait de faire ceci


try {
    //....
    $result = mysql_query($select);
    if ($result===false){throw new Exception("Mon texte d'erreur",E_USER_NOTICE);}
    //....
}catch (Exception $e){print $e->getMessage();exit;}
 

Donc ceci est l'équivalent de ce que tu as écrit précedemment mais plus proprement.
Si tu prends cette habitude, cela sera déjà un bon début.

++

NB: exit ou die() c'est la même chose.

Dernière modification par Jc (03-12-2011 12:41:17)


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

Hors ligne

#97 04-12-2011 11:42:43

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,

Bon en principe j'ai terminée le cron (a part le distribution des gains).

Pour rappel tu m'avais dis :

Pour la 2e partie de ton CRON, voici quel devrait être l'algorithme.
A) On commence par clôturer les courses en cours qui sont terminées.
1) Pour chaque course et donc pour chaque circuit on calcule l'ordre et le temps d'arrivée de chaque pet de la course (d'abord sur la distance puis sur le temps).
2) On met à jour les courses avec ces valeurs exactes calculées pour les valeurs définitives
3) On attribue les récompenses s'il y en a (difficile de le faire après, même si c'est mieux pour alléger le cron mais cela oblige à le faire hors automatisation.
4) On cloture les courses ci-dessus.
B) On lance le départ des courses en attente.
5) On met à jour le statut des courses au départ. 
6) Fin.

Donc ca donne :


// On commence par clôturer les courses en cours qui sont terminées.
$sqlUp = "UPDATE course,pet
          SET course.statut=3, pet.oqp=0
          WHERE (UNIX_TIMESTAMP(depart_theorique)+duree*120) <= UNIX_TIMESTAMP(NOW()) AND statut='2' "
;
mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de Maj cloture course",E_USER_NOTICE);}

 // création de la table memory course
$requete="CREATE TABLE `m_course2` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `id_course` int(10) unsigned NOT NULL,
      `id_pet` int(10) unsigned NOT NULL,
      `dist_parcourue` smallint(5) unsigned NOT NULL,
      `nbparticipants` tinyint(3) unsigned NOT NULL,
      `tps_restant` smallint(5) unsigned NOT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_course` (`id_course`),
      KEY `idx_pet` (`id_pet`)
    ) ENGINE=MEMORY DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci"
;
$result2 = mysql_query($requete);
if ($result2===false){throw new Exception("Erreur de creation de la table m_course2",E_USER_NOTICE);}    

  $sql7="INSERT INTO m_course2 (id_course, id_pet, dist_parcourue, nbparticipants)
      SELECT t1.id_course,t1.id_pet,calc_dist(t2.endurance,t5.ellapsed,t4.puissance_min,t2.puissance,t3.duree) as dist_parcourue, t3.nbparticipants,
      t3.duree-t5.ellapsed AS tps_restant
      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, nbparticipants, ((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(depart)) /60) AS ellapsed FROM course) as t5 ON t1.id_course=t5.id_course
      WHERE t3.statut=3
      ORDER BY dist_parcourue DESC"
;  
  $result7 = mysql_query($sql7);
if ($result7===false){throw new Exception("Erreur de remplissage de la table m_course2",E_USER_NOTICE);}

  // on reverse les ressources gagnées pour les 3 1er pet (respectivement 60% - 20% - 10% de toutes les ressources "misées")

// On archive les courses terminées.
$sqlUp = "UPDATE course,
          SET statut=5
          WHERE statut='3' "
;
$result=mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de maj des course au statut 5",E_USER_NOTICE);}

// On lance le départ des courses en attente.
$sqlUp = "UPDATE course
          SET course.statut=2
          WHERE UNIX_TIMESTAMP(depart_theorique) <= UNIX_TIMESTAMP(NOW()) AND statut='1' "
;
$result=mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de Maj course au statut 2",E_USER_NOTICE);}

}catch (Exception $e){print $e->getMessage();exit;}

?>

 

Alors j'ai un soucis pour la distribution des gains.
Je voudrais bien faire et ne pas faire de select + un while + 3 update... mais du coup je vois pas comment m'y prendre.
Je me dis que ca serai peut etre pa mal d'enregistrer dans la table m_course2 la position final de chaque pet, mais je sais pas comment faire

Pour connaitre et mettre a jour les gains faut :
Récupérer : ressource_type, ressource_quantite FROM course
Les gains sont :
  $gain1 = (60/(ressource_quantite*nbparticipants))*100;
  $gain2 = (20/(ressource_quantite*nbparticipants))*100;
  $gain3 = (10/(ressource_quantite*nbparticipants))*100;

Et faut ensuite faire un update sur la table perso_ressource genre : UPDATE perso_ressource SET bois=(bois+gain1) WHERE id_pet=1er de la course
En sachant que :

function ressource2nom($ressource)
// trouve le nom d'une ressource en fct de son numéro
{
  switch ($ressource)
  {
    case '1':
      $nom = "Bois";
    break;
    case '2':
      $nom = "Herbe";
    break;
    case '3':
      $nom = "Viande";
    break;
    case '4':
      $nom = "Plante";
    break;
    case '5':
      $nom = "Fer";
    break;
    case '6':
      $nom = "Angreal";
    break;
  }
  return $nom; 
}

Une bonne idée?
smile
merci

Dernière modification par ebouilleur (04-12-2011 11:51:13)

Hors ligne

#98 04-12-2011 12:56:43

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,

Excuse moi si j'abrège un peu, mais j'avais tout bien détaillé mes explications, mais suite à une erreur de manipulation, me faut tout réecrire^^.

1) Il te faut mettre ton code dans une instruction try{}catch(){} et tu peux inclure dans le texte de ton erreur l'erreur mysql
2) J'avais précisé qu'une table memory ne serait pas forcément nécessaire, or ici ce que tu as fait ne sert à rien car tu n'utilises même pas les lignes passées dans ta table memory.
3) Pour résoudre ton problème de classement final il te faut d'abord connaître la distance à parcourir de chaque circuit.
4) voici un exemple de comment tu pourrais résoudre ton problème pour ton classement final à partir de là.
a) Ecrire la fonction inverse de calc_dist() et l'appeler calc_time().
b) Calculer pour chaque pet le temps mis à parcourir la distance totale. 2 cas de figure. Si MIN(T)>=20min alors ta requête existante te donne le classement final à 20min. Si MIN(T)<20min et soit T' ce temps, réutiliser la même requête sur une durée de T' pour avoir le classement final.
c) une fois le classement final obtenu, mettre à jour les tables de base avec les valeurs exactes de distance parcourue de chaque pet et la durée totale de la course, 20min ou T'.

Pour le système de récompense je reviens vers toi dès que j'ai 5min..

Bon dimanche.

Dernière modification par Jc (04-12-2011 12:57:50)


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

Hors ligne

#99 04-12-2011 15:53:49

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 :

1) Il te faut mettre ton code dans une instruction try{}catch(){} et tu peux inclure dans le texte de ton erreur l'erreur mysql

le try{ peut etre en tout début de page et le }catch(){} en tout fin de page? ou ca doit etre propre a chaque requete genre :


try{
// On lance le départ des courses en attente.
$sqlUp = "UPDATE course
          SET course.statut=2
          WHERE UNIX_TIMESTAMP(depart_theorique) <= UNIX_TIMESTAMP(NOW()) AND statut='1' "
;
$result=mysql_query($sqlUp);
if ($result===false){throw new Exception("Erreur de Maj course au statut 2",E_USER_NOTICE);}
}catch (Exception $e){print $e->getMessage();exit;}
 
Jc a écrit :

2) J'avais précisé qu'une table memory ne serait pas forcément nécessaire, or ici ce que tu as fait ne sert à rien car tu n'utilises même pas les lignes passées dans ta table memory.

Heu c'est car j'ai oublié de copier la requete qui met a jour la distance dans la table course_participant.
Et je me disais que la table m_course2 serai peut etre utile pour la distribution des gains

Jc a écrit :

3) Pour résoudre ton problème de classement final il te faut d'abord connaître la distance à parcourir de chaque circuit.
4) voici un exemple de comment tu pourrais résoudre ton problème pour ton classement final à partir de là.
a) Ecrire la fonction inverse de calc_dist() et l'appeler calc_time().
b) Calculer pour chaque pet le temps mis à parcourir la distance totale. 2 cas de figure. Si MIN(T)>=20min alors ta requête existante te donne le classement final à 20min. Si MIN(T)<20min et soit T' ce temps, réutiliser la même requête sur une durée de T' pour avoir le classement final.
c) une fois le classement final obtenu, mettre à jour les tables de base avec les valeurs exactes de distance parcourue de chaque pet et la durée totale de la course, 20min ou T'.

Ok pour l'idée, mais si on s'en moque de la distance parcouru. Ce qui importe c'est de courir pendant 20 minutes.
Ce qui me pose pb dans l'immédiat, c'est d'attribuer une position au pet (1, 2 , 3, etc - a sauvegarder dans la table memory ou course_participant?) pour leur donner leur récompense (et aussi un certain score : genre 100pts pour le 1er, 50pts pour le 2eme)
mais peut etre y a t il pas besoin de position pour leur donner leur récompense?

Je vais néanmois réfléchir a faire calc_time()

Merci et désolé que t'es du retaper ton post hmm

PS : le calcule des scores est fait comme ca :


function score_course($position,$nb_participant,$sess_id_pseudo)
{
  $add_point = ($nb_participant+1-$position)*10/$nb_participant;
  $sqlUp = "UPDATE score SET score=(score + $add_point), score_course=(score_course + $add_point) WHERE id_pseudo='$sess_id_pseudo'";  
  mysql_query($sqlUp) or die('Erreur SQL : maj score course!<br>'.$sqlUp.'<br>'.mysql_error());  
}
 

Dernière modification par ebouilleur (04-12-2011 16:28:12)

Hors ligne

#100 05-12-2011 21:08:44

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,

Désolé mais je n'ai pas beaucoup de temps en ce moment.
Le résultat final DOIT être stocké dans la table de jonction (table course_participant) en ce qui concerne les distances parcourues et les temps mis pour chaque pet. Les résultats doivent être exacts car ce sont eux qui feront foi en cas de litige et pour l'attribution des récompenses. Pas besoin de stocker l'ordre des arrivants car c'est ta requête qui te donne l'ordre d'arrivée grâce au ORDER BY dist_parcourue,temps_petcourse.

Pour le try catch c'est un seul try catch pour l'ensemble de ton process. Je t'ai dit ça car je n'ai pas vu le try au début^^.

Voilà.

Dernière modification par Jc (05-12-2011 21:09:35)


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

Hors ligne

Pied de page des forums