If anyone else is looking for a similar solution, this is what I came up with in the end:
SELECT
CONCAT(u.firstname, ' ', u.lastname) Name,
d1.data Cohort,
d2.data School,
d3.data Unit,
d4.data Instructor,
d5.data Days,
c.fullname Course,
IF (ROUND(gg.finalgrade / gg.rawgrademax * 100, 2) > 79, 'Yes', 'No') Complete,
ROUND(gg.finalgrade / gg.rawgrademax * 100, 2) Grade,
DATE_ADD('1970-01-01', INTERVAL gg.timemodified SECOND) 'Date & Time'
FROM prefix_user u
JOIN prefix_user_info_data d1 ON d1.userid = u.id
JOIN prefix_user_info_field f1 ON d1.fieldid = f1.id AND f1.shortname = 'Cohort'
JOIN prefix_user_info_data d2 ON d2.userid = u.id
JOIN prefix_user_info_field f2 ON d2.fieldid = f2.id AND f2.shortname = 'School'
JOIN prefix_user_info_data d3 ON d3.userid = u.id
JOIN prefix_user_info_field f3 ON d3.fieldid = f3.id AND f3.shortname = 'Unit'
JOIN prefix_user_info_data d4 ON d4.userid = u.id
JOIN prefix_user_info_field f4 ON d4.fieldid = f4.id AND f4.shortname = 'Instructor'
JOIN prefix_user_info_data d5 ON d5.userid = u.id
JOIN prefix_user_info_field f5 ON d5.fieldid = f5.id AND f5.shortname = 'Days'
JOIN prefix_user_info_data d6 ON d6.userid = u.id
JOIN prefix_user_info_field f6 ON d6.fieldid = f6.id AND f6.shortname = 'Client'
JOIN prefix_role_assignments ra ON u.id = ra.userid
JOIN prefix_context ctx ON ra.contextid = ctx.id
LEFT JOIN prefix_course c ON c.id = ctx.instanceid
LEFT JOIN prefix_grade_grades gg ON gg.userid = u.id
LEFT JOIN prefix_grade_items gi ON gi.id = gg.itemid
LEFT JOIN prefix_course_categories cc ON cc.id = c.category
WHERE d6.data = '$client name'
GROUP BY u.id
ORDER BY 'Name'
It gets the job done, but takes a very long time to process.