Page 1 sur 2

Classement

Posté : 04 oct. 2005, 10:08
par Steffy
Bonjour, voilà je viens vous demandez de l'aide pour un classement.

En faite j'ai une table qui contient

UTILISATEURS - SCORES - DATE D'ENREGISTREMENT

Je classe ma page en fonction de la date d'enregistrement et les scores sont obtenus grace a un systeme de vote.

ce qui me donne quelque chose comme:

NOM - SCORES - DATE

TOTO - 10 - 03/01/2005
TOTO2 - 5 - 02/01/2005
TOTO3 - 8 - 01/01/2005

Jusqu'ici tout va bien seulement j'aimerais ajouté une colonne classement en focntion du score EXEMPLE:

NOM - SCORES - DATE - CLASSEMENT

TOTO - 10 - 03/01/2005 - 1
TOTO2 - 5 - 02/01/2005 - 3
TOTO3 - 8 - 01/01/2005 - 2

Ma question est comment écrire ce classement dans ma table ?

Voila le code qui additione les scores si ca peu aider...

$DB->simple_construct( array( 'select' => 'SUM(result) AS sc',
'from' => 'mlite_rate',
'where' => "s_id=".$ibforums->input['s_id'] ) );
$DB->simple_exec();
$row = $DB->fetch_row();
$DB->simple_exec_query( array( 'update' => "table_sc", 'set' => "score=".$row['sc'], 'where' => "s_id=".$ibforums->input['s_id'] ) );

Quequ'un aurait il un début de solution ?

Amicalement Steffy!

Posté : 04 oct. 2005, 10:20
par zeus
Avant de t'aider, je voudrais que tu m'explique quelquechose :

ton classement est censé évoluer avec le temps, non ? Les scores ne sont pas fixes ?

Tu sera d'accord avec moi que pour dresser le classement, il faut trier la table ? ;)

Ce que je te conseille, c'est de ne pas stocker le classement, mais de trier la table par score quand tu veux afficher le classement

Sachant que le score et le classement sont des données qui ammènent aux mêmes résultats, je ne suis pas persuadé de son utilité :?

Mais tu as peut être une autre bonne raison pour vouloir ce champ

Posté : 04 oct. 2005, 10:23
par Cyrano
J'appuierais d'autant plus zeus sur ce qu'il vient de mentionner qu'on ne stocke en principe JAMAIS un champ calculé dans une base de données. C'est un peu comme si on stockait les informations sur un membre en stockant aussi son âge: la donnée sera fausse dès le lendemain et il faudra recalculer pour mettre à jour.... pas très optimal ;)

Posté : 04 oct. 2005, 20:09
par Steffy
Bonjour merci pour vos réponses...je suis d'accord sur le faite que ce n'est pas très optimal..

Ceci dit en regardant le tableau je le classe d'abord par DATE et que je tiens a garder ce classement par date.

NOM - SCORES - DATE - CLASSEMENT

TOTO - 10 - 03/01/2005 - 1
TOTO2 - 5 - 02/01/2005 - 3
TOTO3 - 8 - 01/01/2005 - 2

Alors comment lui dire que par score TOTO qui a la plus haute valeur est 1 er TOTO2, 3eme...etc ?

Comment lui donné cette valeur 1,2,3 si je ne stock pas cette info dans ma table ?

J'éspére avoir était clair dans mon explication.

Steffy

Posté : 04 oct. 2005, 20:16
par Truc
SAlut, pour afficher ton classement tu dois bien faire une boucle d'affichage des données triées par Date (directement dans le SQL ça)... alors tu initalise une variable à 1 avant la boucle et a chaque passage tu incrémente le compteur. Et c'est ce compteur qui te servira de classement (1, 2, 3, ..)

Posté : 04 oct. 2005, 20:24
par Cyrano
Il y a un point important sur lequel je vais revenir : une base de donnée permet de stocker des données... mais c'est son seul rôle. Elle n'est pas faite pour stocker des classements, mais des valeurs. Après seulement on peut obtenir des classements de ces valeurs lors de requêtes plus ou moins complexes selon ce qu'on veut obtenir, mais la base de donnée n'est là que pour enregistrer les informations. C'est d'autant plus vrai si ces classements évoluent au fil des mises à jour des valeurs.

Quand tu fais une requête SELECT, il n'y a de limitation au nombre de clauses de tri que le nombre de champs disponibles; Si tu fais un ORDER BY, tu peux mettre tous les champs en commençant par celui que tu veux voir trié dans un sens, à l'intérieur de ce tri, tu peux rajouter le second champ, ce qui fait que si dans la première colonne tu as deux fois ou davantage la même valeur, alors le tri sera effectué en second lieu sur le second champ mentionné dans la clause ORDER BY et ainsi de suite pour chaque champ.

À la sortie en suite lors de l'affichage, tu peux rajouter d'autres valeurs exclusivement réservées à l'affichage comme le classement par exemple avec un pointeur que tu initialises à 1 avant la boucle et que tu incréentes à chaque tour comme te l'as suggéré Truc

Posté : 04 oct. 2005, 21:15
par Steffy
Merci pour vos suggestions ceci dit une question me taraude.

Si je fais un order BY DATE, SCORE

et que j'initialise la valeur 1 au pointeur et qu'ensuite j'incrémente cette valeur de +1...

comment je fais pour qu'il affecte ces valeur a score seulement et non a DATE, SCORE...

par ce que la je risque de me retrouvé avec un tableau du genre...

NOM - SCORES - DATE - CLASSEMENT

TOTO - 10 - 03/01/2005 - 1
TOTO2 - 5 - 02/01/2005 - 2
TOTO3 - 8 - 01/01/2005 - 3


au lieu de

NOM - SCORES - DATE - CLASSEMENT

TOTO - 10 - 03/01/2005 - 1
TOTO2 - 5 - 02/01/2005 - 3
TOTO3 - 8 - 01/01/2005 - 2


Est-ce que je fais fausse route ?

Désolé si la question est idiote :oops:

Posté : 04 oct. 2005, 21:34
par Cyrano
Si tu as deux boucles imbriquées, attention à l'endroit où tu fais ton incrémentation. Sans voit ton code, difficile de te guider très efficacement. Mais sommairement, tu initialises le pointeur avant les boucles, et tu incréments en ajoutant la ligne.

Posté : 04 oct. 2005, 22:37
par Truc
je comprend pas trop comment tu veut trier ton classement en effet tu te contredit il me semble:
Ceci dit en regardant le tableau je le classe d'abord par DATE et que je tiens a garder ce classement par date.
et apres tu dit:
comment je fais pour qu'il affecte ces valeur a score seulement et non a DATE, SCORE...
et ici un tri sur le score et apres la date ( et encore j'en suis meme plus sur de ça :? )

Comme l'a dit Cyrano, tu peut trier les champs sur ce que tu veut:
1ere idée :arrow: SELECT ... ORDER BY date, score
2eme idée :arrow: SELECT ... ORDER BY score,date
à toi de choisir ce qui te convient le mieux ( si tu as compris le principe)

Posté : 04 oct. 2005, 22:54
par Steffy
Bah en faite voila un partie du code....
$DB->simple_construct( array( 'select' => 's.*,c.cat_name',
									  'from'   => 'tablesong s LEFT JOIN '.SQL_PREFIX.'tablecats c ON (s.cat_id=c.cat_id)',
									  'where'  => "s.s_open=1 AND s.cat_id".$ids,
									  'order'  => "s.post_date DESC",
									  'limit'  => array($first,25) ) );
											   
			$query=$DB->simple_exec();
                 $i =1;
			while ( $r = $DB->fetch_row($query) )
			{
                       $r['s_rank'] = $i++;

Le probleme c'est avec ca j'ai le tableau qui m'affiche donc dans la colone classement 1 2 3 dans l'ordre de DATE puisqu'il classé ainsi logique non ?)
NOM - SCORES - DATE - CLASSEMENT

TOTO - 10 - 03/01/2005 - 1
TOTO2 - 5 - 02/01/2005 - 2
TOTO3 - 8 - 01/01/2005 - 3


Seulement moi j'aimerais gardé exactement le meme affichage par date mais que la colone classement afiche le bon classement cad dans l'exemple il devrais affiché 1,3,2 (en fonction de la valeur des scores) est-ce que c'est plus clair ? :roll:

Désolé de vous prendre un peu la tête :oops:

Posté : 04 oct. 2005, 23:03
par Truc
enfait tu veut que l'affichage des données se fasse en fonction de la date MAIS que le classemant suit les point ?!

Hmm, dans ce cas le pointeur qui suit la boucle ne tient plus, sur le coup je vois pas d'alternative. :?

Posté : 04 oct. 2005, 23:07
par Steffy
Oui voilà je crois que tu as compris...c'est donc pourquoi je pensais qu'il faudrait ajouté cette valeur dans la table...et reclassé a chaque vote ce qui n'est pas "optimisé" comme le faisait remarqué plus haut Cyrano je crois.

Posté : 04 oct. 2005, 23:11
par Truc
attends un peu avant de crée ton champ, je suis sur que Cyrano va revenir avec une belle astuce, moi je suis a sec :x (trop de BD pour une heure si tardive :wink: )

Posté : 04 oct. 2005, 23:26
par Cyrano
Effectivement, je vois bien aussi le problème, mais pour l'astuce dans l'immédiat, je vois pas. À priori, il va falloir travailler avec des tableaux: enregistrer toutes les lignes dans un tableau multidimensionnel, classer ça par score, ajouter une élément de classement au tableau pour l'affichage , reclasser ensuite le tableau par dates et enfin afficher ça en page. Très grossièrement, c'est tout ce que je vois pour l'instant :-k

... à moins de récupérer les données classées dans la requête par SCORE et non par date, enregistrer ça dans un tableau, et effectuer un classement du tableau par date avant l'affichage. On ajouterait donc le classement à chaque nouvel ajout dans le tableau dlors de la récupération et on coupe une étape par rapport à l'idée suggérée au départ...

Posté : 04 oct. 2005, 23:33
par Steffy
Oui merci cyrano j'en ai mal a la tête :shock: lol

c'est un casse tête mais quoi qu'il en soit en admettant que j'ai des centaines d'utilisateurs sur le dit site... ce genre de chose risque de faire beaucoup travailler mysql ?