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
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
A voir également:
- Simplifier requêtes multiples sur même table
- Table ascii - Guide
- Table des matières word - Guide
- Table des figures google doc ✓ - Forum Word
- Error accessing config table - Forum Ubuntu
- Schema branchement table de mixage sur ampli - Forum Audio
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 ;)
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 ;)
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
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
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
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
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 :/
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 :/
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
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.
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.
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
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 ?
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 ?
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
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..
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..
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
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...
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...
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
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 ?
// 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 ?