J'ai donc un problème avec ma requête. J'ai 2 tables:

Cours:

Le user_id dans ce tableau est l'instructeur du cours.

-----------------------------------------------------------------------
| course_id   |    user_id    |   course_name     | other information |
-----------------------------------------------------------------------
| 6           |       1       |   My Course 1     | ...               |
-----------------------------------------------------------------------

Mes cours:

Le user_id dans ce tableau est un étudiant du cours.

--------------------------------------------------
| user_id     | course_id  | created_at          |
--------------------------------------------------
| 5           | 6          | [UNIX_TIMESTAMP]    |
--------------------------------------------------

Le my_courses contient le nombre de personnes qui ont rejoint ce cours. Je souhaite obtenir toutes les informations sur le cours ainsi que le nombre de personnes qui ont rejoint un cours. Tout revient comme prévu sauf le nombre de personnes ayant rejoint un cours. Voici la requête que j'utilise:

        SELECT 
            courses.*,
            users.name, //This is the name of the instructor
            users.last_name, //This is the last name of the instructor
            COUNT(my_courses.user_id) as count_students

        FROM courses

        LEFT JOIN users
        ON courses.user_id = courses.user_id

        LEFT JOIN my_courses
        ON courses.course_id = my_courses.course_id

        WHERE courses.course_id = '6'

Comme je l'ai dit, cette requête renvoie les informations du cours comme d'habitude mais renvoie 3 sous la forme count_students alors qu'elle ne doit renvoyer que 1. Quelqu'un sait-il pourquoi cela se produit? Toute aide est grandement appréciée.

-1
Brian Moreno 17 janv. 2017 à 04:08

2 réponses

Meilleure réponse

C'est probablement à cause de la condition JOIN pour users. Ça devrait être:

LEFT JOIN users
        ON courses.user_id = users.user_id

Vous devez également ajouter une clause GROUP BY dans votre requête:

SELECT 
    c.*,
    u.name, 
    u.last_name,
    COUNT(mc.user_id) AS count_students
FROM courses c
LEFT JOIN users u
    ON c.user_id = u.user_id
LEFT JOIN my_courses mc
    ON c.course_id = mc.course_id
WHERE c.course_id = '6'
GROUP BY
    <columns not in the aggregate function>

De plus, alias vos tables pour améliorer la lisibilité.

1
Felix Pamittan 17 janv. 2017 à 01:16

Les opérations JOIN provoquent une multiplication combinatoire des lignes. Vous devez résumer le nombre d'étudiants à partir de son propre tableau comme tel.

                      SELECT course_id, COUNT(*) students
                        FROM my_courses
                    GROUP BY course_id

Cela vous donne un ensemble de résultats avec une ou zéro ligne par course_id. Vous pouvez ensuite le joindre au reste de votre requête.

SELECT courses.*,
       users.name, //This is the name of the instructor
       users.last_name, //This is the last name of the instructor
       aggr.count_students
  FROM courses
  LEFT JOIN users  ON courses.user_id = courses.user_id
  LEFT JOIN (
                 SELECT course_id, COUNT(*) students
                   FROM my_courses
                GROUP BY course_id
       ) aggr ON courses.course_id = aggr.course_id
 WHERE courses.course_id = '6'

De cette façon, vous éviterez de compter plusieurs fois vos étudiants pour des cours avec peut-être plus d'un instructeur.

1
O. Jones 17 janv. 2017 à 01:21