Simplifier requêtes multiples sur même table

Résolu/Fermé
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 - 19 déc. 2009 à 21:08
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 - 20 déc. 2009 à 23:26
Bonsoir tout le monde,

J'ai un petit site de pronostics sur lequel je fais des dizaines de calculs ne serait-ce qu'au chargement de n'importe quelle page (car la colonne de gauche de ma page, fixe, affiche les divers classements). Je fais donc des dizaines de requêtes mais je pense qu'il y a moyen de faire plus simple.. :(

Exemple d'une de mes bases : elle regroupe les résultats essentiels des membres, à savoir leur nombre de points, leur classement général, leur classement relatif, leur classement indicié, le nombre de p1, de p2, p3...

Admettons que je veuille afficher le classement général.

'SELECT login, classement_general FROM classements ORDER BY classement_general ASC';
.... plus le reste qui mène à l'affichage

Si je veux le classement relatif, toujours accessible depuis cette base, rebelotte :
'SELECT login, classement_relatif FROM classements ORDER BY classement_relatif ASC';
.... plus le reste qui mène à l'affichage

Et puis j'ai aussi un classement déduit d'un indice ! Rebelotte..

N'y a-t-il pas moyen de simplifier tout ça ? De faire une requête genre SELECT * FROM classements, de mettre le résultat entier dans un tableau et de manipuler plus simplement après ?

Les tableaux, j'utilise jamais et j'ai beaucoup de mal à comprendre.

Merci pour vos lumières.

8 réponses

Salut,

voici quelques suggestions que je peux te faire:

- Condenser tes requêtes (utilise les jointures, au lieu de faire 10 requêtes utilises en juste 1)
- Utiliser les sessions pour conserver les infos (ex: au login conserve les infos qui ne changeront jamais durant sa session)

Si tu utilises ces 2 éléments tu pourras surement obtenir un meilleur temps d'exécution et ce seras plus simple de travailler sur les données ;)
0
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 192
20 déc. 2009 à 01:26
Salut fredou,

Merci de ta réponse.
Bon je me suis mal exprimé pour commencer, il faut remplacer "base" par "table" dans mon premier message.
En fait je n'ai qu'une seule table qui contient les données les plus importantes. Les jointures c'est entre plusieurs tables non ?

@puche
0
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 192
20 déc. 2009 à 11:14
Re,

J'ai cherché un peu, et suis tombé sur ce qu'on appelle une auto-jointure. Bonne direction ?

Je vais être plus explicite en prenant un cas où je ne ferais que 2 requêtes dans une (si c'est possible).
Voilà ma table classements :

login | clas_general | clas_relatif
---------------------------------------------
jean | 2 | 1
pierre | 1 | 2

Actuellement, pour afficher les 2 classements je fais ceci :

requête 1 :
$sql = 'SELECT * FROM classements ORDER BY clas_general ASC';
$res = mysql_query.....
while ($retour = mysql_fetch_array($res) echo '' . retour['login'] . ':' . retour['clas_general'] . '<br />';
mysql_close($link);

requête 2 :
$sql = 'SELECT * FROM classements ORDER BY clas_relatif ASC';
$res = mysql_query.....
while ($retour = mysql_fetch_array($res) echo '' . retour['login'] . ':' . retour['clas_relatif'] . '<br />';
mysql_close($link);

Il faut savoir que j'effectue au-moins 5 de ces opérations sur la même table, là il n'y en a que 2.

Une fonction ça le ferait pas ? Du genre :

fonction (choix)
{
$sql = 'SELECT * FROM classements ORDER BY choix ASC';
$res = mysql_query.....
while ($retour = mysql_fetch_array($res) echo '' . retour['login'] . ':' . retour['choix'] . '<br />';
mysql_close($link);
}

Et encore ça ne concerne que les classements, car en plus j'ai des requêtes différentes sur la même table. Donc en fait même si c'est faisable de cette manière c'est pas très intéressant en fait :/
0
moderno31 Messages postés 870 Date d'inscription mardi 23 juin 2009 Statut Membre Dernière intervention 8 août 2012 92
20 déc. 2009 à 11:18
Oui les jointures sont entre 2 tables au plus car après ça produit des résultats incohérents meme si syntaxe pas fausse.
Faut avoir les bons ID aux bons endroits, des index si volume important...
Je veux bien essayer de t'aider. Donc soit plus clair dans tes détails.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 192
20 déc. 2009 à 11:43
Salut moderno,

Hum le problème c'est que je peux pas être plus explicite :/

Grosso modo, on a affaire à une table unique avec pour entrées concernant un pronostiqueur :
- un login
- un classement général
- un classement relatif
- un classement déduit d'un indice (peu importe, c'est juste un classement)
- le nombre de premières places
- le nombre de secondes places
- le nombre de troisièmes places

Afin d'afficher ces données je fais actuellement autant de requêtes qu'il y a de champs : 1 pour le classement général, 1 pour le classement relatif, 1 pour l'indicié, 1 pour p1, etc..

Ca fait des dizaines de lignes, un grand nombre de requêtes, et je me demandais s'il était possible de largement simplifier tout ça.

Je pense que pour ce qui concerne les classements, l'utilisation de la fonction que je mets au-dessus fonctionnerait. Ca simplifierait donc. Mais peut-on aller plus loin ?
0
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 192
20 déc. 2009 à 11:51
Pour te donner une idée de ce à quoi ça ressemble, voilà :
http://aeroport.calais.free.fr/pronos/classement.php?annee=2009

J'ai bâti ce petit site il y a un an, il a bien fonctionné depuis. Je profite de l'inter-saison pour l'améliorer un peu, mais ça reste à mon niveau..
0
moderno31 Messages postés 870 Date d'inscription mardi 23 juin 2009 Statut Membre Dernière intervention 8 août 2012 92
20 déc. 2009 à 17:40
ça reste à ton niveau mais c'est vachement bien fait...bravo.

Coté S.I
Fait moi voir le script de chacune de tes requetes (pour chaque table concernée, indique moi le volume à peu près). Je te dirai si ya une possibilité. Parce là comme ça je n'ai pas de visibilité.

sinon envoie moi un script SQL complet sans les données (structure seulement) j'installer de mon coté je jette un coup 10min et je te réponds ... ce sera aussi rapide.

Après faut voir des données que tu requetes. Si tu fais du comptage, faut en général agréger donc en général tu peux pas faire autrement. Si c'est du dimensionnement, il faut faire appel aux jointures poour récupérer en une req autant d'informations possible...
0
Bertrand40 Messages postés 1193 Date d'inscription vendredi 27 mars 2009 Statut Membre Dernière intervention 27 février 2023 192
20 déc. 2009 à 23:26
Alors j'ai créé des fonctions ! Je te montre un aperçu d'une : (au passage ça te permet d'avoir ce que tu me demandais en Q1. dans ton msg)

// FONCTION DE CALCUL DES CLASSEMENTS (LIMITE = 3 PREMIERS RESULTATS)
function calcul_classements($choix)
{
// on récupère le score max pour faire le différentiel de points
$sql = 'SELECT MAX(' . $choix . ') FROM pronos_classement';
$res = mysql_query($sql,$link) or die("Erreur SQL : $query<br/>".mysql_error());
$max = mysql_fetch_array($res);
mysql_close($link);

// nouvelles variables pour besoins graphiques
if ($choix == 'points_totaux') { $type = 'Classement général'; $type_pts = 'Total'; }
if ($choix == 'moyenne') { $type = 'Classement relatif'; $type_pts = 'Pts/course'; }
if ($choix == 'tot_global') { $type = 'Classement indice'; $type_pts = 'Indice'; }

if ($choix != 'points_totaux') echo '<fieldset style="border: 1px solid;"><legend>' . $type . '</legend>';
echo '<table><tr><td style="background: #707C92; color: white;">Joueur</td><td style="background: #707C92; color: white;">' . $type_pts . '</td></tr>';

$sql = 'SELECT * FROM pronos_classement ORDER BY ' . $choix . ' DESC LIMIT 0,3';
$res = mysql_query($sql,$link) or die("Erreur SQL ICI: $query<br/>".mysql_error());

if (mysql_num_rows($res) == 0) echo '<tr><td>non défini</td><td>non défini</td></tr>';
else while ($retour = mysql_fetch_array($res))
{
$diff = $max[0] - $retour[$choix];
$diff = str_replace('.', ',', $diff);
$retour[$choix] = str_replace('.', ',', $retour[$choix]);

if ($diff == 0)
{
$diff = '';
echo '<tr><td>' . $retour['login'] . '</td><td>' . $retour[$choix] . '</td></tr>';
}

else echo '<tr><td>' . $retour['login'] . '</td><td>' . $retour[$choix] . ' <span style="font-size: 10px;">(-' . $diff . ')</span></td></tr>';
}

mysql_close($link);

echo '</table>';
if ($choix != 'points_totaux') echo '</fieldset>';
}

// AFFICHAGE
calcul_classements(points_totaux);
calcul_classements(moyenne);
calcul_classements(tot_global);


Cette fonction m'a permis de transformer 150 lignes en 45. Première question, est-ce que dans ce cas la longueur du script change grand chose à la donne ? En gros est-ce que j'y ai gagné (perdu) quoique ce soit en terme de rapidité ?

Une seconde me permet d'afficher le résumé saison que tu as lorsque tu cliques sur le lien donné plus haut : total 50 lignes de script au lieu de 200.

Q2. Je te prépare le script sql de la structure de la base (jamais fait.. j'imagine que ça fait partie des fonctions de phpmyadmin, donc pas trop compliqué).

Q3. Ben je crois que j'agrège en effet, donc a priori d'après toi y a pas grand chose de plus à faire.

Sur ce bonne nuit et merci pour ton compliment :)
A la base on utilise ce site en famille et on peut pas dire que je sois très encouragé.. Enfin.. je m'éclate, c'est déjà pas mal. Merci de t'intéresser à mes questions également. @+

PS : je sais pas si c'est très malin de vous donner le code brut avec le nom de mes tables.. non ?
0