I am using the Moodle database to query the latest forum posts made by students and teachers for the relevant course they are enrolled in.
Here are the tables I need to join and an explanation in what they hold:
mdl_forum_posts = “all posts are stored in this table”
mdl_forum_discussions = “forums are composed as discussions”
mdl_user = “information stored about users”
mdl_log = “activity of every user of the system be it, log in – adding a post”
mdl_user_enrolments = “users participating in courses”
mdl_enrol = “instances of enrolment plugins used in mdl_course”
mdl_course = “courses available in the system”
Here is my query:
SELECT l.time AS TimeofPost, l.action as Action, usr.id as UserID, usr.firstname,usr.lastname, c.id as CourseID , c.fullname, c.idnumber, fd.name, fd.timemodified as CreatedOn, fp.created, fp.modified, fp.subject, fp.message FROM mdl_forum_posts fp LEFT JOIN mdl_forum_discussions fd ON fp.discussion = fd.id LEFT JOIN mdl_user usr ON fp.userid = usr.id LEFT JOIN mdl_log l ON usr.id = l.userid LEFT JOIN mdl_user_enrolments ue ON usr.id = ue.userid LEFT JOIN mdl_enrol e ON ue.enrolid = e.id LEFT JOIN mdl_course c ON e.courseid = c.id WHERE (action = 'add post' OR action = 'add discussion')
The problem I have is that I am getting duplicate results.
Advertisement
Answer
No need to use the logs table – the fact that a post has been added and has a timestamp is all you need. Also, you don’t really want to use LEFT JOIN unless you expect null values, which should never be the case here. I’ve left in the link to the enrolment table so that if any students are unenrolled, they won’t show up, but this isn’t really necessary.
You are getting duplicates because there are multiple matches for each forum post e.g. enrol table has many instances for each course. This query makes sure you just get stuff where there is one.
SELECT fp.id, usr.id as UserID, usr.firstname, usr.lastname, c.id as CourseID, c.fullname, c.idnumber, fd.name, fd.timemodified as DiscussionCreatedOn, fp.created AS TimeofPost, fp.modified, fp.subject, fp.message FROM mdl_forum_posts fp INNER JOIN mdl_forum_discussions fd ON fp.discussion = fd.id INNER JOIN mdl_forum f ON f.id = fd.forum INNER JOIN mdl_course c ON f.course = c.id INNER JOIN mdl_user usr ON fp.userid = usr.id WHERE EXISTS (SELECT 1 FROM mdl_user_enrolments ue INNER JOIN mdl_enrol e ON ue.enrolid = e.id WHERE usr.id = ue.userid AND e.courseid = f.course)