Page 1 sur 1
diminuer le nombre de requêtes
Posté : 07 oct. 2006, 09:13
par Florent
Bonjour
Imaginons une table membre avec les champs suivants : id , pass et login
Je désire sur la page de sommaire faire un truc du style :
Il y a actuellement 700 membres inscrits
Je fais donc une requête de ce style :
Code : Tout sélectionner
$retour = mysql_query("SELECT COUNT(*) AS nbre_entrees FROM membre");
$donnees = mysql_fetch_array($retour);
Et si je veux ajouter :
Le dernier membre inscrit est machin, bienvenue à lui
Suis-je obligé de faire une nouvelle requete ou existe t-il une possibilité à select count (*) d'extraire la valeur du dernier champ login ?
(id est auto-increment)
Deuxième question : avec count(*) peut-on mettre une clause comme distinct login ?
Car dans mon système, login peu être dupliqué.
merci pour l'aide.
Posté : 07 oct. 2006, 09:16
par fabien_14
Il me semble que tu est obliger de faire 2 requetes séparément.
Réponse Question N2 : Oui Avec COUNT (DISTINCT )
SELECT COUNT (DISTINCT login) FROM membre ;
Posté : 07 oct. 2006, 11:32
par Florent
Et bien je te remercie.
Posté : 07 oct. 2006, 13:03
par Cyrano
J'ajouterais que pour avoir le dernier, si ta clé primaire est un entier auto-incrémenté, tu peux récupérer la ligne avec MAX(colonne-identifiant).
Et en fait tu pourrais tout avoir en un seule requête. Proposition vite faite, il y a peut-être mieux :
Suppose la structure de table
personnes suivante :
Code : Tout sélectionner
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| pers_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| pers_nom | varchar(32) | NO | | NULL | |
| pers_prenom | varchar(32) | NO | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
Avec comme contenu :
Code : Tout sélectionner
+---------+----------+-------------+
| pers_id | pers_nom | pers_prenom |
+---------+----------+-------------+
| 1 | Peuplus | Jean |
| 2 | Connu | Augustin |
| 3 | Affeu | Pierre |
+---------+----------+-------------+
On a trois membres, le dernier identifiant est 3. On va extraire le nombre total des membre et les informations du dernier inscrit :
Code : Tout sélectionner
mysql> SELECT COUNT(p1.pers_id) AS nbre_entrees, MAX(p2.pers_id) AS dernier_membre, p2.pers_nom, p2.pers_prenom
-> FROM `personnes` AS p1, `personnes` AS p2
-> GROUP BY p2.pers_nom
-> LIMIT 1;
+--------------+----------------+----------+-------------+
| nbre_entrees | dernier_membre | pers_nom | pers_prenom |
+--------------+----------------+----------+-------------+
| 3 | 3 | Affeu | Pierre |
+--------------+----------------+----------+-------------+
1 row in set (0.02 sec)
Attention à ne pas oublier la clause LIMIT, sinon tu auras une ligne par membre.
Posté : 07 oct. 2006, 13:26
par Florent
Merci pour le petit cours

J'ai essayé ça ne marche pas mais j'ai dû mal adapté ce modèle à mes tables, je dois bien avouer que je ne suis pas encore assez calé.
Mais je le garde de côté.
Posté : 07 oct. 2006, 13:56
par Cyrano
Je ne sais pas si tu as noté, mais la requête comporte une auto-jointure : on travaille donc vitruellement sur deux tables distinctes et non sur une seule. C'est peut-être la raison pour laquelle ton adaptation n'a pas fonctionné.
Posté : 07 oct. 2006, 14:34
par Hubert Roksor
Hmm, je ne suis pas trop sûr pour l'auto-jointure sans condition de jointure (pas de JOIN ... ON), j'ai peur que les performances se dégradent de façon exponentielle. Je recommanderais plutôt de le faire en deux requêtes (deux requêtes simples valent souvent mieux qu'une compliqué):
Code : Tout sélectionner
SELECT MAX(pers_id) AS pers_id, COUNT(pers_id) AS total
FROM personnes
puis en utilisant la valeur de
pers_id
Code : Tout sélectionner
SELECT pers_nom, pers_prenom
FROM personnes
WHERE pers_id = 123
Selon ta version de MySQL, Florent, tu peux même les combiner :
Code : Tout sélectionner
SELECT tmp.total, tmp.pers_id, p.pers_nom, p.pers_prenom
FROM (
SELECT MAX(pers_id) AS pers_id, COUNT(pers_id) AS total
FROM personnes
) AS tmp
JOIN personnes AS p USING (pers_id)
Explication : la requête que tu vois entre parenthèse après le FROM est ce qu'on a appelle une "table dérivée". En fait c'est comme si on créait une table temporaire dont le contenu serait le résultat de la requête. Et comme cette table n'a pas de nom, on lui donne un alias avec "AS" (dans notre exemple on l'appelle "tmp"). Tu noteras qu'on a aussi utilisé un alias ("p" dans mon exemple) pour accéder à la table "personnes"... parce que c'est plus court à écrire et à lire
Donc d'un côté on a notre table dérivée qui contient le total des utilisateurs et l'ID de l'utilisateur le plus récent et de l'autre on a la table "personnes", et pour les joindre on utilise le champs "pers_id". [
voir le manuel de JOIN ] [
tutorial sur les jointures SQL ]
Posté : 07 oct. 2006, 14:44
par Cyrano
Impressionné je suis
Hubert
Je me doutais qu'on pouvait faire mieux que mon petit bricolage rapide

Posté : 08 oct. 2006, 11:41
par Hubert Roksor
Merci, mais en fait je triche un peu parce que j'ai une longueur d'avance. Ça fait un bout de temps que je me suis posé la même question, et après quelques tests j'en étais arrivé à cette conclusion. :]
Posté : 08 oct. 2006, 19:03
par Florent
Merci pour ce cours.
Va falloir que je m'y mette très sérieusement.
En tout cas, merci.