JOINTURES EN TABLES
.
<?php
class postManager {
private $_bdd;
public function __construct($bdd) {
$this->setDb($bdd);
}
public function setDb(PDO $dbh) {
$this->__bdd = $dbh;
}
public function getSchoolsStudentsNumbers() {
$query = 'SELECT ecole.id, schools_name, SUM(schools_id)
FROM ecole LEFT JOIN eleves ON ecole.id = eleves.schools_id GROUP BY ecole.id';
$stmnt = $this->__bdd->prepare($query);
$stmnt->execute();
while($row = $stmnt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
public function getSchoolsSportStudentsNumbers() {
$query = 'SELECT ecole.id, schools_name, SUM(schools_id) FROM ecole LEFT JOIN eleves ON ecole.id = eleves.schools_id';
$stmnt = $this->__bdd->prepare($query);
$stmnt->execute();
while($row = $stmnt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
}
?>
<?php
require('class/postManager.php');
try {
$bdd = new PDO('mysql:host=localhost;dbname=ecoles', '10111110', '10111110');
}
catch(exception $e) {
die('Erreur ' . $e->getMessage());
}
$bdd->exec("SET CHARACTER SET utf8");
$manager = new postManager($bdd);
$results = $manager->getSchoolsStudentsNumbers();
var_dump($results);
?>
<h1>Voici le nombre d'élèves appartenent à telle école</h1>
<table>
<?php if(!empty($results)) : ?>
<?php foreach($results as $result) : ?>
<thead>
<tr>
<th>N° Identification</th>
<th>Nom de l'école</th>
<th>Le nombre d'élèves par école</th>
</tr>
</thead>
<tr>
<td><?php echo $result['id']; ?></td>
<td><?php echo $result['schools_name']; ?></td>
<td><?php echo $result['SUM(schools_id)']; ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</table>
Bonjour, j'aimerais restituer la liste des écoles en affichant pour chacune :
– le nombre d’élèves, (cela est fait). (1)
– le nombre d’élèves pratiquant au moins un sport, (2)
– le nombre d’activités sportives pratiquées, (3)
ça coince au niveau (2 et 3
Réponses apportées à cette discussion
Sans les descriptions exactes des tables, difficile d'apporter une réponse sûre.
Ensuite, « ça coince », c'est plutôt léger comme description d'un problème. Il serait plus approprié d'indiquer ce qui est attendu et ce qui est effectivement obtenu.
Enfin, il y a une erreur dans la construction du tableau, la partie thead va se répéter avec chaque ligne, il faudrait la décaler entre le foreach et le if.
bdd -> ecoles
table -> ecole
nom des champs -> id, schools_name
table -> eleves
nom des champs -> id, students_name, students_name_first, schools_id
table -> eleves_sports
nom des champs -> id, students_id, sports_id
table -> sports
nom des champs -> id, sports_name
-- Nombre d'élèves par école
SELECT
E.id,
E.schools_name,
COUNT(*) AS nb_eleves
FROM
ecole E
INNER JOIN eleves S
ON E.id = S.schools_id
GROUP BY E.id, E.schools_name
-- Nombre d'élèves avec sport par école
SELECT
S.schools_id,
COUNT( DISTINCT S.id ) AS nb_eleves
FROM
eleves S
INNER JOIN eleves_sports SS
ON S.id = SS.students_id
GROUP BY S.schools_id
-- Nombre de sports pratiqués par école
SELECT
S.schools_id,
COUNT( DISTINCT SS.sports_id ) AS nb_sports
FROM
eleves S
INNER JOIN eleves_sports SS
ON S.id = SS.students_id
GROUP BY S.schools_id
-- Afficher dans l'ordre les sports pratiqué en fonction du nombre d'élèves.
SELECT S.schools_id, SP.sports_name AS liste_sports, COUNT(DISTINCT S.id) AS nb_eleves
FROM eleves AS S
LEFT JOIN eleves_sports AS SS
ON S.id = SS.students_id
LEFT JOIN sports AS SP
ON SS.sports_id = SP.id
GROUP BY S.schools_id, SP.sports_name
Voilà j'ai fait cela, mais je n'arrive pas à afficher dans l'ordre les sports pratiqué en fonction du nombre d'élèves.
Merci d'avance
Juste pour être sûr : si j'ai compris correctement, sur ces quatre requêtes, les trois premières donnent le résultat attendus, mais pas la quatrième, c'est bien ça ?
Pour tester, je me suis reproduit la base avec un jeu d'essai : 4 écoles, 200 élèves et 5 sports, puis j'ai repris la dernière requête et apporté une modification :
SELECT
el.schools_id,
sp.sports_name AS liste_sports,
COUNT(el.id) AS nb_eleves
FROM sports sp
LEFT OUTER JOIN eleves_sports ep ON sp.id = ep.sports_id
LEFT OUTER JOIN eleves el ON ep.students_id = el.id
GROUP BY el.schools_id, sp.sports_name
J'obtiens un résultat qui semble cohérent, à tester, il faudrait voir si c'est bien ce qui est attendu. Ce que j'ai fait : inverser l'ordre des jointures.
Le résultat que j'ai obtenu :
+------------+--------------+-----------+
| schools_id | liste_sports | nb_eleves |
+------------+--------------+-----------+
| 1 | athlétisme | 9 |
| 1 | Basketball | 9 |
| 1 | Cyclisme | 15 |
| 1 | Judo | 9 |
| 1 | Tennis | 5 |
| 2 | athlétisme | 9 |
| 2 | Basketball | 12 |
| 2 | Cyclisme | 8 |
| 2 | Judo | 9 |
| 2 | Tennis | 11 |
| 3 | athlétisme | 15 |
| 3 | Basketball | 12 |
| 3 | Cyclisme | 9 |
| 3 | Judo | 8 |
| 3 | Tennis | 18 |
| 4 | athlétisme | 12 |
| 4 | Basketball | 10 |
| 4 | Cyclisme | 8 |
| 4 | Judo | 9 |
| 4 | Tennis | 3 |
+------------+--------------+-----------+
Et on a par école et par sport le nombre d'élèves correspondant. Mais là, c'est basé sur un jeu de données où un élève ne pratique qu'un seul sport. Et le total de la colonne « nb_eleves » est bien de 200, c'est à dire le nombre total des élèves enregistrés dans la table.
Je te remercie, mais ils sont toujours pas dans l'ordre, je m'explique :
école 1 = Cyclisme -> 15 élèves, Athlétisme -> 9, Basketball -> 9,
Judo -> 9, Tennis -> 5.
Je les veux dans cet ordre grouper par école.
Merci d'avance & bonne journée
Ben il suffit d'ajouter une clause ORDER BY en indiquant ici schools_id et nb_eleves
Super çà marche. Merci bien & bon weekend
Pareillement ;-)
Encore moi, petit soucis -> Nombre d'élèves avec sport par école
Le résultat retourné devrait être 8 pour les trois écoles alors qu'il m'affiche 10.
Effectivement il y a 8 élèves qui pratiquent au moins un sport et 2 élèves qui n'en pratiquent pas donc 0 dans sports_id
Merci d'avance
Ben là, je ne sais pas, pour l'exemple, je suis parti d'un jeu d'essai monté à l'arrache en ligne, chaque élève ne fait qu'un seul port, et tous en font un. Il faudrait modifier ces données pour faire sauter quelques liens sport/élève et en rajouter d'autres pour certains qui en ont déjà. Mais cette requête devrait malgré tout sortir les bons chiffres.
Il faudrait me montrer la requête finale telle qu'elle est exécutée et le résultat obtenu, avec en marge, le résultat attendu