8768 sujets

Développement web côté serveur, CMS

Bonjour a vous!

J'ai un problème qui m’empêche de dormir depuis hier. Avec la crise du covid19, je me suis lancé avec deux amis dans la création d'une plateforme d'e-learning et on est butter sur une requête qui nous empêche d'avanver

Alors on a le schéma suivant:

Utilisateurs(-idUser, login, pass)

Profils(#idUser, nom, prenom, sexe)

Professeurs(#idUser, grade)

Etudiants(#idUser, #idClasse, matricule)


Notre but est de faire une requête qui sélectionne un utilisateur, son profil et, s'il est un professeur, on récupère son grade, s'il est un étudiant, on récupérera plutôt sa classe et son matricule.



On devrait donc avoir l'un des cas suivant

* Pour un professeur ==> idUser, login, mdp, nom, prenom, sexe, grade
* Pour un etudiant ==> idUser, login, mdp, nom, prenom, sexe, idClasse, matricule


On a essayer les requêtes suivantes mais sans avoir le résultats attendu


SELECT * FROM utilisateurs As u
INNER JOIN profils As p ON p.idUser = u.idUser
LEFT JOIN professeurs As pr ON pr.idUser = u.idUser 
LEFT JOIN etudiants As e ON e.idUser = u.idUser

Ici, on récupère bien les éléments, sauf que pour un étudiant donné , on a le champ grade qui apparaît avec la valeur ?null ?et pour un professeur donné les champs matricule et classe apparaissent également


SELECT * FROM utilisateurs As u, profils As p, etudiants As e WHERE u.idUser = e.idUser AND u.idUser = p.idUser 
UNION
SELECT * FROM utilisateurs As u, profils As p, professeurs As pr WHERE u.idUser = pr.idUser AND u.idUser = p.idUser

Ici, on a une erreur SQL : << Le nombre de colonne ne correspond pas >>


SELECT * FROM utilisateurs As u, profils As p
WHERE u.idUser = p.idUser AND (
    u.idUser IN (SELECT idUser FROM etudiants) 
    OR 
    u.idUser IN (SELECT idUser FROM professeurs)
)

Ici, seuls les champs des tables utilisateurs et profils sont renvoyés. ceux des deux autres tables sont ignorés.

Si vous pourriez nous donner un coup de main ça serait cool
Modifié par Dimtrovich (21 Apr 2020 - 11:59)
Bonjour Dimtrovich,
Pour moi, la première requête est la plus cohérente. A mon avis (qui n'engage que moi), il faut la laisser telle quelle et faire la distinction prof/étudiant derrière lors du traitement (en PHP j'imagine) avec un truc du genre :

if(!is_null($retour_bdd['grade'])){ } //C'est un prof
elseif(!is_null($retour_bdd['matricule'])){ } //C'est un étudiant
else{} //Erreur

Après je suis pas un pro du SQL, il y a peut-être moyen d'optimiser la requête!
Bon courage
Effectivement @Mathieu c'est la solution qu;on a adopté pour le moment.
Mathieu8337 a écrit :


if(!is_null($retour_bdd['grade'])){ } //C'est un prof
elseif(!is_null($retour_bdd['matricule'])){ } //C'est un étudiant
else{} //Erreur



Même comme c'est pas trop cool. On voulais optimiser un peu les performances en limitant au max les sous traitements mais bon... on gère d'abord comme sa en attendant

Merci bien
On a finalement eu a faire quelques traitements supplémentaires


<?php 
function exist($id, $table) {
    $result = $db->prepare('SELECT COUNT(u.idUser) FROM utilisateurs AS u NATURAL JOIN '.$table.' As t WHERE u.idUser = ?');
    $result->execute([$id]);
    $nbr = $result->fetchColumn();
    $result->closeCursor();
    return $nbr > 0;
}

$idUser = $_SESSION['idUser'];

if(exist($idUser, 'professeurs')) {
    $result = $db->prepare('SELECT * FROM utilisateurs AS u NATURAL JOIN professeurs WHERE u.idUser = ?');
    $result->execute([$idUser]);
    $user = $result->fetch(PDO::FETCH_OBJ);
    $result->closeCursor();
}
else {
    $result = $db->prepare('SELECT * FROM utilisateurs AS u NATURAL JOIN etudiants WHERE u.idUser = ?');
    $result->execute([$idUser]);
    $user = $result->fetch(PDO::FETCH_OBJ);
    $result->closeCursor();
} 

if(empty($user) {
    // Utilisateur  inexistant
} 
else {
    // Traitement
}
?>


Etant donné qu'un utilisateur est soit eu etudiant, soit un prof, on aura donc les informationd voulues normalement
Modifié par Dimtrovich (26 Apr 2020 - 12:13)