[MySQL] Nombre de cours et exercices avec une seules requête

Nombre de cours et exercices avec une seules requête [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 22-03-2019 à 10:31:19    

Bonjour,
 
J'ai plusieurs tables:
- Cours: id, id_modules, nom
- Exercices: id, id_modules, nom
- Modules: id, nom
- Users2mocules: id_modules, user_id
- Users2cours: user_id, cours_id, actif (0 ou 1 si actif ou non)
- Users2exercices: user_id, exercice_id, actif (0 ou 1 si actif ou non)
- Users: id, nom
 
Je cherche à obtenir en une seule requête, un résultat du type suivant pour un id de user donné:
id_module - nom_module - nbCours - NbExercices
 
Avec "nbCours" et "nbExercices", le nombre de cours et d'exercices accessibles à la personne, et qui sont actifs.
J'arrive à obtenir un résultat pour seulement soit les cours, soit les exercices mais pas les 2...
 

Code :
  1. SELECT
  2.         m.id,
  3.       m.nom,
  4.         COUNT(*) AS nbCours
  5.      FROM
  6.       cours c
  7.      INNER JOIN
  8.       users2modules u2m
  9.       ON u2m.id_modules = c.id_modules
  10.       AND u2m.id_user = 75
  11.       AND u2m.actif = 1
  12.      INNER JOIN
  13.       users2cours u2c
  14.       ON u2c.id_user = u2m.id_user
  15.       AND u2c.actif = 1
  16.      INNER JOIN
  17.       modules m
  18.       ON m.id = c.id_modules
  19.      WHERE
  20.       u2c.id_cours = c.id
  21.      GROUP BY m.nom


 
 
Ce que je tente pour avec le nombre d'exercices en plus, et qui donc ne fonctionne pas:
 

Code :
  1. SELECT
  2.         m.id,
  3.       m.nom,
  4.         COUNT(c.id) AS nbCours,
  5. COUNT(e.id) AS nbExercices
  6.      FROM
  7.       cours c,
  8. exercices e
  9.      INNER JOIN
  10.       users2modules u2m
  11.       ON u2m.id_modules = c.id_modules
  12.       AND u2m.id_user = 75
  13.       AND u2m.actif = 1
  14.      INNER JOIN
  15.       users2cours u2c
  16.       ON u2c.id_user = u2m.id_user
  17.       AND u2c.actif = 1
  18.      INNER JOIN
  19. users2exercices u2e
  20. ON u2e.id_user = u2m.id_user
  21. AND u2e.actif = 1
  22.      INNER JOIN
  23.       modules m
  24.       ON m.id = c.id_modules
  25.      WHERE
  26.       u2c.id_cours = c.id
  27.      GROUP BY m.nom


 
J'obtiens comme erreur que "c.ud_modules" n'existe pas.
 
Par avance, merci pour votre aide! :)

Reply

Marsh Posté le 22-03-2019 à 10:31:19   

Reply

Marsh Posté le 22-03-2019 à 14:55:12    

Pour ton erreur je dirait que tuas fait une coquille en écrivant ud_modules au lieu de id_modules ! ^^
 
A vue de nez, (j'ai lut en diagonal), tu devrais changer tes jointures en dur INNER en jointure souple LEFT, car tu as surement des modules qui n'ont pas d'exercices et d'autres pour qui ce sera le contraire.
 
Il faudra aussi que tu fasses un COUNT(DISTINCT(c.id)) et COUNT(DISTINCT(t.id)) pour ne pas fausser tes résultats en comptant en double.
 
Les jointures c'est assez complexe à comprendre, moi ça m'a pas mal aidé de tester des trucs dans phpMyAdmin (genre supprimer le GROUP BY) pour mieux appréhender.
 
https://sqlpro.developpez.com/cours/sqlaz/ensembles/


Message édité par mechkurt le 22-03-2019 à 14:56:41

---------------
D3
Reply

Marsh Posté le 22-03-2019 à 15:01:23    

+1 pour les LEFT JOIN pour les jointures entre modules et exos/cours mais aussi entre les cours/users et exos/users.
Les jointures, c'est juste une histoire de théorie des ensembles (en maths) : https://fr.wikipedia.org/wiki/Jointure_(informatique)


Message édité par rufo le 22-03-2019 à 15:02:27

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 27-03-2019 à 11:11:21    

Bonjour,
 
Concernant les INNER JOIN c'était fait exprès en fait car je ne veux pas les modules qui ne possèdent pas d'exercice, mais c'est vrai que j'avais oublié de le préciser.
 
J'ai pu ce matin arriver à ce que je voulais avec des requêtes imbriquées, c'est plus long mais ça a le mérite de fonctionner parfaitement.
 
Je vais aller voir les adresses que vous donnez, c'est toujours bon d'en savoir plus.
 
Merci! :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed