Ad-hoc DB query from 1.9 to 2.4 question

Ad-hoc DB query from 1.9 to 2.4 question

i le Judy Hsu -
Number of replies: 7

Hi,

We used to have this following DB query (run on the Ad-hoc DB query block) running fine on Moodle 1.9 to do monthly forum participation report, and after we upgraded to 2.4, this query no longer works for some reasons... Can anyone see what's wrong with this query running on Moodle 2.4? Thanks!

 

SELECT lo.course AS Course_ID, co.shortname AS Course_ShortName, co.fullname AS Course_FullName, r.name, COUNT(r.name) as Forum_Posts
FROM prefix_log lo
INNER JOIN prefix_course co ON (co.id = lo.course)
INNER JOIN prefix_user us ON (lo.userid = us.id)
INNER JOIN prefix_role_assignments ra ON (ra.userid = us.id)
INNER JOIN prefix_context ctxt ON (ctxt.id = ra.contextid AND
ctxt.instanceid = co.id AND ctxt.contextlevel = 50)
INNER JOIN prefix_role r ON (r.id  = ra.roleid)
WHERE lo.action LIKE '%add%' AND FROM_UNIXTIME(lo.time) > '201x-xx-xx' AND FROM_UNIXTIME(lo.time) < '201x-xx-xx' AND lo.course <> 1 AND lo.module = 'forum'
GROUP BY Course_ID, r.name
ORDER BY co.fullname

Average of ratings: -
In reply to Judy Hsu

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

What is the error message if you try to run that query directly in MySQL?

In reply to Tim Hunt

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Judy Hsu -

Hi Tim, thanks for your help.

I changed the query to run directly on MySQL, it did not generate any error, just NO results (while it should have some results).

I am thinking that maybe the "context" part of the query has been changed from Moodle 1.9 to 2.3 (or 2.4)? In my query I had:

INNER JOIN prefix_context ctxt ON (ctxt.id = ra.contextid AND
ctxt.instanceid = co.id AND ctxt.contextlevel = 50)

However, when I go to this Moodle page (regarding Roles and modules), it mentioned that "this article is now obsolete." Any idea? Thanks again.

 

In reply to Judy Hsu

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Darko Miletić -

You assume that your query should return results. This query will not return results if you do not have users enrolled in the context of a course for which the log entry was created.

Query could also be a bit optimized. 

AND FROM_UNIXTIME(lo.time) > '201x-xx-xx' is not good way to do it since you force mysql to convert EVERY value of lo.time to date and than implicitly compare it to another date. 

This is much better - lo.time > UNIX_TIMESTAMP('YYYY-MM-DD') - with this mysql will create timestamp value just once and use that to directly compare it to lo.time which is much faster.

To confirm or deny if you actually have a users with some role in courses of your choice replace INNER JOINS to LEFT JOINS for the role part. And finally in Moodle 2 roles can now have name overrides on per context level which should be checked too.

Modified query would look like this:

SELECT 
    lo.course AS Course_ID,
    co.shortname AS Course_ShortName,
    co.fullname AS Course_FullName,
    CASE WHEN rn.name IS NULL THEN r.name 
         ELSE rn.name END AS RoleName,
    COUNT(r.name) AS Forum_Posts
FROM       mdl_log              AS lo
INNER JOIN mdl_course           AS co   ON (co.id = lo.course)
INNER JOIN mdl_user             AS us   ON (lo.userid = us.id)
INNER JOIN mdl_context          AS ctxt ON (ctxt.instanceid = co.id) AND (ctxt.contextlevel = 50)
LEFT  JOIN mdl_role_assignments AS ra   ON (ra.userid = us.id) AND (ctxt.id = ra.contextid)
LEFT  JOIN mdl_role             AS r    ON (r.id = ra.roleid)
LEFT  JOIN mdl_role_names       AS rn   ON (rn.roleid = r.id) AND (rn.contextid = ctxt.id)
WHERE
       lo.action LIKE '%add%'
       AND lo.time > UNIX_TIMESTAMP('2013-09-01') 
       AND lo.time < UNIX_TIMESTAMP('2013-09-30')
       AND co.id > 1
       AND lo.module = 'forum'
GROUP BY Course_ID , r.name
ORDER BY co.fullname

 Also in the code query table prefixes should never be hardcoded. Instead use {table} format which moodle replaces to a correct table name.

But with all this said what puzzles me is why would you do it this way? Is it not easier to just look at forum_posts table and get all that information from there?

 

 

 

In reply to Darko Miletić

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Judy Hsu -

Hi Darko, thanks a million for your help!

I have another quick question. So this is a old query that we run on Moodle 1.9 before, to capture how many days teachers logged in to the LMS during a certain time period:

SELECT lo.course AS Course_ID, co.shortname as Course_ShortName, co.fullname AS Course_FullName, us.firstname as Instructor_FirstName, us.lastname AS Instructor_LastName, COUNT(DISTINCT(FROM_UNIXTIME(lo.time, '%Y-%m-%d'))) AS Days_Logged_In
FROM prefix_log lo
INNER JOIN prefix_course co ON (co.id = lo.course)
INNER JOIN prefix_user us ON (lo.userid = us.id)
INNER JOIN prefix_role_assignments ra ON (ra.userid = us.id)
INNER JOIN prefix_context ctxt ON (ctxt.id = ra.contextid AND ctxt.instanceid = co.id AND ctxt.contextlevel = 50)
INNER JOIN prefix_role r ON (r.id  = ra.roleid)
WHERE lo.course <> 1 AND r.name='Instructor'
AND (FROM_UNIXTIME(lo.time) > '2013-09-10' AND FROM_UNIXTIME(lo.time) < '2013-09-14') AND (co.shortname LIKE '%13/FALL%' OR co.shortname LIKE '%13/SPRING%')
GROUP BY us.firstname, us.lastname, Course_ID, Course_ShortName, Course_FullName
ORDER BY co.fullname, co.shortname

This query now seems to have some trouble to run correctly on Moodle 2.4. Do you see anything wrong with this query or can you make some suggestions about how to improve this query? Thanks again!

In reply to Judy Hsu

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Anne Krijger -

Hi Judy,

You don't mention why you assume it has trouble, nor what that trouble might be.
The query itself seems a bit constructed, but the one listed below runs on my 2.4 system and gives a result that seems appropriate.

Anne.
--
SELECT lo.course AS Course_ID, co.shortname as Course_ShortName, co.fullname AS Course_FullName, us.firstname as Instructor_FirstName, us.lastname AS Instructor_LastName, COUNT(DISTINCT(FROM_UNIXTIME(lo.time, '%Y-%m-%d'))) AS Days_Logged_In
FROM mdl_log lo
INNER JOIN mdl_course co ON (co.id = lo.course)
INNER JOIN mdl_user us ON (lo.userid = us.id)
INNER JOIN mdl_role_assignments ra ON (ra.userid = us.id)
INNER JOIN mdl_context ctxt ON (ctxt.id = ra.contextid AND ctxt.instanceid = co.id AND ctxt.contextlevel = 50)
INNER JOIN mdl_role r ON (r.id  = ra.roleid)
WHERE lo.course <> 1
-- AND r.name='Instructor'
-- AND (FROM_UNIXTIME(lo.time) > '2013-09-10' AND FROM_UNIXTIME(lo.time) < '2013-09-14') AND (co.shortname LIKE '%13/FALL%' OR co.shortname LIKE '%13/SPRING%')
GROUP BY us.firstname, us.lastname, Course_ID, Course_ShortName, Course_FullName
ORDER BY co.fullname, co.shortname

In reply to Anne Krijger

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Judy Hsu -

Hi Anne, thanks for helping out. I found that I had a missing ")" in the original query and that's probably why it didn't run.. it's a human error. Thanks again for your kind help.

In reply to Judy Hsu

Re: Ad-hoc DB query from 1.9 to 2.4 question

i le Darko Miletić -

Well you have the same errors as in previous query. You use FROM_UNIXTIME(lo.time) > '2013-09-10' when it should be the other way arround etc.