Domanda

my SQL is a bit rusty after 2 years of not having studied it, so I can't find a way to do this.

I need to get some data from a Moodle database, namely some averages of feedback tests where students rate their teachers.

This SQL query:

SELECT mdl_course.id, mdl_user.username FROM mdl_course
INNER JOIN mdl_context ON mdl_context.instanceid = mdl_course.id
INNER JOIN mdl_role_assignments ON mdl_context.id = mdl_role_assignments.contextid
INNER JOIN mdl_role ON mdl_role.id = mdl_role_assignments.roleid
INNER JOIN mdl_user ON mdl_user.id = mdl_role_assignments.userid
WHERE mdl_role.id = 3

returns something like this, a table with each course and its teacher as assigned.

COURSE_ID TEACHER   
2          john
3          mary
4          john

Now, my second SQL is like this:

SELECT mdl_feedback.course, AVG(mdl_feedback_value.value) as average
FROM mdl_feedback_value 
INNER JOIN mdl_feedback_item ON mdl_feedback_value.item = mdl_feedback_item.id 
INNER JOIN mdl_feedback ON mdl_feedback.id = mdl_feedback_item.feedback
INNER JOIN mdl_feedback_completed ON mdl_feedback.id = mdl_feedback_completed.feedback
INNER JOIN mdl_user ON mdl_feedback_completed.userid = mdl_user.id
GROUP BY mdl_feedback.course

COURSE    AVERAGE   
2          3.5
3           3
4          3.25

What I want is to combine those 2 SQL queries into one that goes like this, using COURSE/COURSE_ID as the key

TEACHER    AVERAGE
john         3,375   <--- avg of 3,5 and 3,25 from each of john's courses
mary         3       <--- she has just one course so no math here

I'm not sure on how to go for this, so I appreciate a bit of help :) As I said, I haven't used SQL for a while so I'm not keen in those JOIN thingies, maybe I have to use them as I have used them here.

I'm using MySQL 5.5.33, and although this is related to Moodle, the answer is not really Moodle-centered as the only thing important here is what tables as the output from both queries.

Thanks

È stato utile?

Soluzione

If you take each of the subqueries and then try to JOIN them, it should work. I added a third field to help you see the detail of how the score was created.

SELECT username, AVG(average) AS average
  , GROUP_CONCAT(CONCAT('Course: ', teachers.course_id,' with score ', COALESCE(average,'No Score Found'))) AS detail
FROM (
    SELECT mdl_course.id AS course_id, mdl_user.username AS username
    FROM mdl_course
    INNER JOIN mdl_context ON mdl_context.instanceid = mdl_course.id
    INNER JOIN mdl_role_assignments ON mdl_context.id = mdl_role_assignments.contextid
    INNER JOIN mdl_role ON mdl_role.id = mdl_role_assignments.roleid
    INNER JOIN mdl_user ON mdl_user.id = mdl_role_assignments.userid
    WHERE mdl_role.id = 3 ) AS teachers
LEFT JOIN (
    SELECT mdl_feedback.course AS course_id, AVG(mdl_feedback_value.value) as average
    FROM mdl_feedback_value 
    INNER JOIN mdl_feedback_item ON mdl_feedback_value.item = mdl_feedback_item.id 
    INNER JOIN mdl_feedback ON mdl_feedback.id = mdl_feedback_item.feedback
    INNER JOIN mdl_feedback_completed ON mdl_feedback.id = mdl_feedback_completed.feedback
    INNER JOIN mdl_user ON mdl_feedback_completed.userid = mdl_user.id
    GROUP BY mdl_feedback.course) AS scores
  ON teachers.course_id = scores.course_id
GROUP BY username

Altri suggerimenti

I am Trying to use a temp table to store the two different query result sets and then later i am querying the temp table to get the average of the teacher. Hope this works.

CREATE TABLE #TEMP
(
COURSE_ID int,
TEACHER varchar(100),
COURSE int,
AVERAGE int
)
--- Inserting the course_id and Teahcer data----

INSERT INTO #TEMP
(
COURSE_ID,
TEACHER
)
SELECT mdl_course.id, mdl_user.username FROM mdl_course
INNER JOIN mdl_context ON mdl_context.instanceid = mdl_course.id
INNER JOIN mdl_role_assignments ON mdl_context.id = mdl_role_assignments.contextid
INNER JOIN mdl_role ON mdl_role.id = mdl_role_assignments.roleid
INNER JOIN mdl_user ON mdl_user.id = mdl_role_assignments.userid
WHERE mdl_role.id = 3

-- Inserting the course and average data---
INSERT INTO #TEMP
(
COURSE,
AVERAGE
)
SELECT mdl_feedback.course, AVG(mdl_feedback_value.value) as average
FROM mdl_feedback_value 
INNER JOIN mdl_feedback_item ON mdl_feedback_value.item = mdl_feedback_item.id 
INNER JOIN mdl_feedback ON mdl_feedback.id = mdl_feedback_item.feedback
INNER JOIN mdl_feedback_completed ON mdl_feedback.id = mdl_feedback_completed.feedback
INNER JOIN mdl_user ON mdl_feedback_completed.userid = mdl_user.id
GROUP BY mdl_feedback.course


--- Querying the # temp table for the average and teacher---

SELECT TEACHER, AVG(AVERAGE)
FROM #TEMP
GROUP BY TEACHER

You could try joining the two queries using

INNER JOIN mdl_course ON mdl_feedback.course = mdl_course.id

Please see if this combined query works:

SELECT mdl_user.username, AVG(mdl_feedback_value.value) as average
FROM mdl_feedback_value 
INNER JOIN mdl_feedback_item ON mdl_feedback_value.item = mdl_feedback_item.id 
INNER JOIN mdl_feedback ON mdl_feedback.id = mdl_feedback_item.feedback
INNER JOIN mdl_feedback_completed ON mdl_feedback.id = mdl_feedback_completed.feedback
INNER JOIN mdl_user ON mdl_feedback_completed.userid = mdl_user.id
INNER JOIN mdl_course ON mdl_feedback.course = mdl_course.id
INNER JOIN mdl_context ON mdl_context.instanceid = mdl_course.id
INNER JOIN mdl_role_assignments ON mdl_context.id = mdl_role_assignments.contextid
INNER JOIN mdl_role ON mdl_role.id = mdl_role_assignments.roleid
INNER JOIN mdl_user ON mdl_user.id = mdl_role_assignments.userid
WHERE mdl_role.id = 3
GROUP BY mdl_user.username;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top