Très souvent une requête SELECT va renvoyer un ensemble d'enregistrements. Pour traiter cet ensemble le plus simple est d'utiliser une boucle while sous la forme suivante :

    while ($enr = mysqli_fetch_assoc($r)) {
    	... traitement de l'enregistrement ...
    }

On utilise le principe du raccourci vu précédemment :

- la fonction mysqli_fetch_assoc() est exécutée
- son résultat est affecté à la variable $enr
- si la valeur de $enr est évaluée comme TRUE, le bloc while est exécuté,
- sinon la boucle while est arrêtée.

Fonctionnement interne de mysqli_fetch_assoc() :

- L'objet mysqli_result renvoyé par mysqli_query() dans le cas d'une requête SELECT dispose d'un pointeur interne qui, au retour de l'appel de mysqli_query(), pointe sur le premier enregistrement sélectionné ("situé à l'indice" 0).
- Chaque appel de mysqli_fetch_assoc() renvoie l'enregistrement courant désigné par ce pointeur interne (ie un tableau associatif qui le représente), puis incrémente le pointeur interne.
- Ainsi, le premier appel de mysqli_fetch_assoc() renvoie le premier enregistrement du résultat, le deuxième appel de mysqli_fetch_assoc() renvoie le deuxième enregistrement du résultat, ..., jusqu'à ce qu'il n'y ait plus de résultat. mysqli_fetch_assoc() renvoie alors NULL.

L'exemple suivant sélectionne tous les auteurs de la base de données de test.

Exemple : sélection multiple
<?php ob_start(); require('bib_params.php'); require('bib_fonctions.php'); htmlDebut('Sélection des auteurs'); $bd = bdConnecter(); //-- Requête ---------------------------------------- $sql = 'SELECT auNom, auPrenom, auPays FROM auteurs'; $r = mysqli_query($bd, $sql) or bdErreur($bd, $sql); //-- Traitement ------------------------------------- while ($enr = mysqli_fetch_assoc($r)) { htmlProteger($enr); echo $enr['auNom'], '<br>', $enr['auPrenom'], '<br>', $enr['auPays'], '<hr>'; } // Libération de la mémoire associée au résultat de la requête mysqli_free_result($r); //-- Déconnexion ------------------------------------ mysqli_close($bd); htmlFin(); ?>

Ce qui est intéressant avec les sélections d'un ensemble d'éléments, c'est qu'on peut demander que les résultats soient triés (ORDER BY) selon un ou plusieurs champs, et par ordre croissant (ASC : valeur par défaut) ou par ordre décroissant (DESC).

L'exemple suivant sélectionne le titre de tous les livres, leur année de parution et le nom de l'éditeur. La sélection est triée par année en ordre décroissant (ie les nouveautés en début de liste).

Exemple : sélection multiple ordonnée
<?php ob_start(); require('bib_params.php'); require('bib_fonctions.php'); htmlDebut('Sélection livres / éditeurs'); $bd = bdConnecter(); //-- Requête ---------------------------------------- $sql = 'SELECT liTitre, liAnnee, edNom FROM livres, editeurs WHERE edID = liIDEditeur ORDER BY liAnnee DESC'; $r = mysqli_query($bd, $sql) or bdErreur($bd, $sql); //-- Traitement ------------------------------------- while ($enr = mysqli_fetch_assoc($r)) { htmlProteger($enr); echo $enr['liTitre'], '<br>', $enr['liAnnee'], '<br>', $enr['edNom'], '<hr>'; } // Libération de la mémoire associée au résultat de la requête mysqli_free_result($r); //-- Déconnexion ------------------------------------ mysqli_close($bd); htmlFin(); ?>

On peut aussi utiliser la clause GROUP BY pour regrouper des éléments et effectuer des calculs avec des fonctions comme count, sum, min ... (documentation MySQL ici ).

L'exemple suivant sélectionne le nom des éditeurs et le nombre de livres proprosés. La sélection est triée par nom. A noter l'utilisation d'un alias pour nommer le résultat de la fonction count.

Exemple : sélection multiple ordonnée et groupée
<?php ob_start(); require('bib_params.php'); require('bib_fonctions.php'); htmlDebut('Sélection livres / éditeurs'); $bd = bdConnecter(); //-- Requête ---------------------------------------- $sql = 'SELECT edNom, count(*) as nbLivres FROM editeurs, livres WHERE liIDEditeur = edID GROUP BY edNom ORDER BY edNom'; $r = mysqli_query($bd, $sql) or bdErreur($bd, $sql); //-- Traitement ------------------------------------- while ($enr = mysqli_fetch_assoc($r)) { htmlProteger($enr); echo $enr['edNom'], '<br>', $enr['nbLivres'], '<br>'; } // Libération de la mémoire associée au résultat de la requête mysqli_free_result($r); //-- Déconnexion ------------------------------------ mysqli_close($bd); htmlFin(); ?>

Si on voulait trier les résultats par nombre de livres, il suffit d'utiliser le nom de l'alias dans la clause ORDER BY comme par exemple :
ORDER BY nbLivres, edNom ou
ORDER BY nbLivres DESC, edNom.

Si on voulait récupérer tous les noms des éditeurs, y compris ceux qui ne proposent pas de livres, il faudrait utiliser une jointure externe et compter le nombre de lignes avec un champ liID non NULL. On pourrait donc utiliser la requête suivante :
SELECT edNom, count(liID) as nbLivres
FROM editeurs
LEFT OUTER JOIN livres ON liIDEditeur = edID
GROUP BY edNom
ORDER BY edNom