Moodle - Report to determine how long it takes before a student's assignment is graded - moodle

I am using Moodle LMS and I need to run a report to find out how long it takes between the time a student submits any sort of human-gradable assignment and the time it is graded so that we can monitor our staff's efficiency. Right now I am going for a query similar to the one below. I still need to add in the actual assignments but I am not sure which items in moodle could possibly fit into the "submitted but waiting to be graded" category.
Which tables am I missing for this query and is there anything I am obviously doing wrong here?
SELECT c.shortname AS course_name
, cm.id AS cmid
, cm.course AS courseid
, md.name AS modname
, gi.itemname AS itemname
, u.firstname AS student_first
, u.lastname AS student_last
, f.firstname AS grader_first
, f.lastname AS grader_last
, NULLIF(GREATEST(IFNULL(g.overridden, 0)
,IFNULL(g.timecreated, 0)
,IFNULL(g.timemodified, 0))
,0) AS graded_unixtimestamp
FROM mdl_user u
JOIN mdl_user_enrolments ue
ON (u.id = ue.userid)
JOIN mdl_enrol e
ON (e.id = ue.enrolid)
JOIN mdl_course c
ON (c.id = e.courseid)
JOIN mdl_course_modules cm
ON (c.id = cm.course)
JOIN mdl_modules md
ON (md.id = cm.module)
JOIN mdl_grade_items gi
ON (
gi.itemmodule = md.name
AND gi.iteminstance = cm.instance
AND gi.courseid = cm.course)
LEFT
JOIN mdl_grade_grades g
ON (gi.id = g.itemid AND g.userid = u.id)
LEFT
JOIN mdl_user f
ON (g.usermodified = u.id);

Related

Randomize students in Moodle

I have a Moodle classroom of about 60 students. All the students have to give a presentation. Is it possible to randomize the students in Moodle to decide the order of presentation?
I can't think of anything in Moodle that will do that.
But you could use SQL - replace xxx with the course id and RANDOM() with the relevant random function for your database
SELECT RANDOM() AS randid, u.id AS userid, u.firstname, u.lastname, u.email
FROM mdl_user u
JOIN (
SELECT DISTINCT ue.userid, e.courseid
FROM mdl_user_enrolments ue
JOIN mdl_enrol e ON e.id = ue.enrolid
) ue ON ue.userid = u.id
JOIN mdl_course c ON c.id = ue.courseid
WHERE c.id = xxx
AND u.deleted = 0
AND u.suspended = 0
ORDER BY 1

Correlated subquery in Postgres

I have a query like below to find the stock details of certain products.The query is working fine but i think it is not efficient and fast enough(DB: postgresql version 11).
There is a CTE "result_set"in this code where i need to find the "quantity of a product ordered"(qty_last_7d_from_oos_date) during the period between out of stock and last 7 days before out of stock date.Same like this i have to find the revenue also.
So what i did is wrote a same subquery two times one outputting the revenue and other the quantity which is not an efficient step.So someone have any suggestions on how to rewrite this and make it an efficient code.
WITH final as
(
SELECT product_id,product_name,item_sku,out_of_stock_at
,out_of_stock_at - INTERVAL '7 days' as previous_7_days
,back_in_stock_at
FROM oos_base
)
SELECT product_id,product_name,item_sku,out_of_stock_at,previous_7_days
,back_in_stock_at
,(SELECT coalesce(sum(i.qty_ordered), 0) AS qty_last_7d_from_oos_date
FROM ol.orders o
LEFT JOIN ol.items i ON i.order_id = o.order_id
LEFT JOIN ol.products p ON p.product_id = i.product_id AND i.store_id = p.store_id
WHERE o.order_state_2 IN('complete','processing')
AND f.product_id=p.product_id
AND o.created_at_order :: DATE BETWEEN f.previous_7_days::DATE AND COALESCE(f.out_of_stock_at::DATE,current_date)
)
,( SELECT coalesce(sum(i.row_amount_minus_discount_order), 0) AS rev_last_7d_from_oos_date
FROM ol.orders o
LEFT JOIN ol.items i ON i.order_id = o.order_id
LEFT JOIN ol.products p ON p.product_id = i.product_id AND i.store_id = p.store_id
WHERE o.order_state_2 IN('complete','processing')
AND f.product_id=p.product_id
AND o.created_at_order :: DATE BETWEEN f.previous_7_days::DATE AND COALESCE(f.out_of_stock_at::DATE,current_date)
)
FROM final f
In the above code the CTE "final" gives you two dates "out_of_stock_at" &
"previous_7_days". I want to find the quantity and revenue of a product based on this 2 dates means between "previous_7_days" & "out_of_stock_at".
Below query will give the quantity and revenue of the products but the period between "previous_7_days" & "out_of_stock_at"from the above CTE.
As of now i have used the below code two times to obtain the information of revenue and quantity.
SELECT coalesce(sum(i.qty_ordered), 0) AS qty ,
coalesce(sum(i.row_amount_minus_discount_order), 0)
FROM ol.orders o
LEFT JOIN ol.items i ON i.order_id = o.order_id
LEFT JOIN ol.products p ON p.product_id = i.product_id AND i.store_id = p.store_id
WHERE o.order_state_2 IN('complete','processing')
AND f.product_id=p.product_id
AND o.created_at_order :: DATE BETWEEN f.previous_7_days::DATE AND COALESCE(f.out_of_stock_at::DATE,current_date)

Trying to . convert a value to a name during output

the values returned in column a.user_id are id numbers. I would like to return them as a name or initials e.g. 1 = Chris O or C.ONeill
I have tried CASE function but did not know where to put it
SELECT DISTINCT
sb.start_time::date AS shift_date,
i.title AS industry,
wl.name AS venue_name,
w.first_name,
w.last_name,
MIN(cs.start_time::date) AS first_completed_shift,
i.title AS industry,
w.interviewed_on AS induction_date,
d.issue_date AS edbs_issue_date,
d.created_at AS date_dbs_added,
a.user_id --IS IT POSSIBLE TO GET THESE AS VALUES,e.g. a.user_id '1' = 'Chris O or C.ONeill' USING USER NAMES INSTEAD OF USER ID?
FROM shift_bookings sb
JOIN jobs j ON sb.job_id = j.id
JOIN listings l ON j.listing_id = l.id
JOIN work_locations wl ON l.venue_id = wl.id
JOIN workers w ON sb.worker_id = w.id
JOIN completed_shifts cs ON w.id = cs.worker_id
JOIN documents d ON w.id = d.documentable_id
JOIN audits a ON d.id = a.auditable_id
JOIN industries i ON j.industry_id = i.id
WHERE sb.shift_id IN (253106)
AND d.document_type_id = 33
AND a.auditable_type = 'Document'
GROUP BY
sb.start_time::date,
wl.name,
w.first_name,
w.last_name,
i.title,
w.interviewed_on,
d.issue_date,
d.created_at,
a.user_id
a.user_id output will be something else I can set

Postgres UPDATE statement

I have moved from mysql to psql, but find it hard to get my head around the UPDATE statement using multiple left joins.
How would you rewrite this in Postgres? (I am using postresql 9.4)
update task t
left join project p on t.project_id = p.id
left join client c on t.client_id = c.id
left join user u on t.user_id = u.id
set t.project_name = p.name,
t.client_name = c.name,
t.user_name = u.name;
Any pointer will be welcome.
Here you go:
WITH task_data AS (
SELECT t.id,
p.name AS project_name,
c.name AS client_name,
u.name AS user_name
FROM task t
LEFT JOIN project p ON t.project_id = p.id
LEFT JOIN client c ON t.client_id = c.id
LEFT JOIN "user" u ON t.user_id = u.id
)
UPDATE task t
FROM task_data d
SET
project_name = d.project_name,
client_name = d.client_name,
user_name = d.user_name
WHERE t.id = d.id
I would be curious to see if there is a more efficient way

Grades of each quiz in Moodle

I'm trying to get grades of each question, I have a query but it only return final grade of whole exam, but i want grade of each question, how to get it?
Here is query that i have:
SELECT mdl_grade_items.id AS ItemID,
mdl_course.shortname AS CourseShortname,
mdl_grade_items.itemname AS ItemName,
mdl_grade_items.grademax AS ItemGradeMax,
mdl_grade_items.aggregationcoef AS ItemAggregation,
mdl_grade_grades.finalgrade AS FinalGrade,
mdl_user.username AS StudentID,
mdl_user.id
FROM mdl_grade_items
INNER JOIN mdl_grade_grades
ON mdl_grade_items.id = mdl_grade_grades.itemid
INNER JOIN mdl_role_assignments
ON mdl_grade_grades.userid = mdl_role_assignments.userid
AND mdl_grade_items.courseid = mdl_role_assignments.mdlcourseid
INNER JOIN mdl_course
ON mdl_course.id = mdl_grade_items.courseid
INNER JOIN mdl_user
ON mdl_user.id = mdl_role_assignments.userid
Ok, i found it
SELECT mqa.id,meqi.grade * (select fraction from mdl_question_attempt_steps where
questionattemptid = mqas.questionattemptid and state like 'mangr%' order by id desc limit
1 ) finalgrade,me.course , mqas.userid,u.firstname, u.lastname, mqa.questionsummary,
mqa.responsesummary , meqi.grade
FROM mdl_question_attempts mqa
left JOIN mdl_question_attempt_steps mqas ON mqa.id = mqas.questionattemptid
left JOIN mdl_user u ON mqas.userid = u.id
left JOIN mdl_examm_question_instances meqi ON meqi.question = mqa.questionid
left JOIN mdl_examm me ON meqi.examm = me.id
WHERE me.course= $courseID and userid = $userID