diminuer le nombre de requêtes

Eléphant du PHP | 114 Messages

07 oct. 2006, 09:13

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.

Eléphant du PHP | 183 Messages

07 oct. 2006, 09:16

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 ;
_________
Fabien

Eléphant du PHP | 114 Messages

07 oct. 2006, 11:32

Et bien je te remercie.

Mammouth du PHP | 19672 Messages

07 oct. 2006, 13:03

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.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 114 Messages

07 oct. 2006, 13:26

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é.

Mammouth du PHP | 19672 Messages

07 oct. 2006, 13:56

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é.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

07 oct. 2006, 14:34

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 ]

Mammouth du PHP | 19672 Messages

07 oct. 2006, 14:44

Impressionné je suis Hubert :agenouille:
Je me doutais qu'on pouvait faire mieux que mon petit bricolage rapide :mrgreen:
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

08 oct. 2006, 11:41

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. :]

Eléphant du PHP | 114 Messages

08 oct. 2006, 19:03

Merci pour ce cours.
Va falloir que je m'y mette très sérieusement.
En tout cas, merci.