Système de jointure dans requête.

Petit nouveau ! | 3 Messages

26 janv. 2016, 11:59

Bonjour à tous,

je viens demander vos lumières. :wink:
Je suis actuellement dans le développement d'un système d'abonnement et je souhaiterais afficher en début de tableau les différents abonnements d'une personne listé dans une boucle while.

Voici l'exemple de mes deux tables
TABLE "CLIENTS"
ID_client | Nom_client | Prenom_client |
1 | BEBONS | Brigitte
2 | PHILIPINS | Auguste
3 |CONSIVAL | Jean
4 |PLUAUD | Régis

TABLE "ABONNEMENT"
ID | ID_client | Nom_abonnement |
1 | 2 | Cardio
2 | 2 | Sophro
3 | 3 | cardio
4 | 1 | Cardio

Comme le montre les tableaux ci-dessus Philipins Auguste a 2 abonnement actif.
Je souhaiterai pouvoir afficher avec un système de jointure ses deux abonnements en début de ligne lors de l'affichage de ma requête juste avant le nom et prénom de la personne.

Voici ma requête actuelle qui affiche.

Code : Tout sélectionner

<?php $reponse = $bdd->query("SELECT * FROM CLIENTS ORDER BY ID_client ASC"); while ($donnees = $reponse->fetch()) { echo $donnees['Nom_client']; echo $donnees['Prenom_client']; echo '<br />'; } ?>
Merci pour votre aide. :wink:

ynx
Mammouth du PHP | 586 Messages

26 janv. 2016, 18:00

Salut,

Une solution possible avec une simple jointure :
$reponse = $bdd->query("SELECT c.ID_client, c.Nom_client, c.Prenom_client, a.ID AS ID_abonnement, a.Nom_abonnement FROM CLIENTS c LEFT JOIN ABONNEMENT a ON c.ID_client = a.ID_client ORDER BY c.ID_client ASC");
Cette requête va donc retourner tous les abonnements de tous les clients. Si un client possède 2 abonnements, la requête va retourner deux lignes pour le même client. Pour éviter d'afficher plusieurs fois le même nom de client lors du parcours des résultats dans la boucle foreach, il faudra enregistrer dans une variable temporaire le nom du client afin de ne l'afficher qu'une seule fois.

Puisqu'un long discours ne vaut pas 3 lignes de codes, voici un exemple :
// supposons que la requête retourne le jeu de résultat suivant
$result = array(
  array('ID_client' => '1', 'Nom_client' => 'BEBONS', 'Prenom_client' => 'Brigitte', 'ID_abonnement' => '4', 'Nom_abonnement' => 'Cardio'),
  array('ID_client' => '3', 'Nom_client' => 'CONSIVAL', 'Prenom_client' => 'Jean', 'ID_abonnement' => '3', 'Nom_abonnement' => 'Cardio'),
  array('ID_client' => '2', 'Nom_client' => 'PHILIPINS', 'Prenom_client' => 'Auguste', 'ID_abonnement' => '1', 'Nom_abonnement' => 'Sophro'),
  array('ID_client' => '2', 'Nom_client' => 'PHILIPINS', 'Prenom_client' => 'Auguste', 'ID_abonnement' => '2', 'Nom_abonnement' => 'Cardio')
);

$nomClient = '';

foreach ($result as $donnees) { // ce foreach correspond à ta boucle while ($donnees = $reponse->fetch())
    // si le client en cours n'a pas été affiché (ce qui est toujours le cas lors du premier tour de boucle)
    if ($nomClient != $donnees['Nom_client']) {
        // on enregistre le nom du client afin de ne pas l'afficher une seconde fois (cf. condition ci-dessus)
        $nomClient = $donnees['Nom_client'];

        // on affiche le nom du client
        echo 'Client : ' . $donnees['Nom_client'] . ' ';
        echo $donnees['Prenom_client'] . '<br>';
    }

    echo 'Abonnement n°' . $donnees['ID_abonnement'] . ' : ';
    echo $donnees['Nom_abonnement'] . '<br>';
}
Note : l'exemple d'affichage ci-dessus ne fonctionne que si le jeu de résultat est bien trié selon le nom du client (ORDER BY c.ID_client)

Bonne journée