How can this be modified with an update statement? Want to update the field "email" in the "mdl_user" table with a value of "users#domain.com" with all records that are returned by this statement
SELECT DISTINCT u.id AS userid, c.id AS courseid
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid
AND ct.contextlevel =50
JOIN mdl_course c ON c.id = ct.instanceid
AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid
AND r.shortname = 'student'
WHERE e.status =0
AND u.suspended =0
AND u.deleted =0
AND ue.status =0
AND courseid =1538
This will update all the selected users:
UPDATE mdl_user
JOIN (
SELECT DISTINCT u.id AS userid, c.id AS courseid
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid
AND ct.contextlevel =50
JOIN mdl_course c ON c.id = ct.instanceid
AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid
AND r.shortname = 'student'
WHERE e.status =0
AND u.suspended =0
AND u.deleted =0
AND ue.status =0
AND courseid =1538
) AS a
ON a.userid = mdl_user.id
SET email = 'users#domain.com'
Related
Please help me to combine this two SQL statement so that it will in the $sql and will be interconnected. The final output is in the $sql and I can use member_status as field. Thanks
SELECT UID.data FROM prefix_user_info_field UIF,
prefix_user_info_data UID WHERE UID.fieldid = UIF.id AND
UIF.shortname = 'member_status' AND UID.userid = U.id) as 'member_status'";
$sql = "SELECT ci.id, u.id as userid, $userfields, co.id as courseid,
co.fullname as coursefullname, c.id as certificateid,
c.name as certificatename, c.verifyany
FROM {customcert} c
JOIN {customcert_issues} ci
ON c.id = ci.customcertid
JOIN {course} co
ON c.course = co.id
JOIN {user} u
ON ci.userid = u.id
WHERE ci.code = :code";
$sql = "SELECT ci.id, u.id as userid, $userfields, co.id as courseid,
co.fullname as coursefullname, c.id as certificateid,
c.name as certificatename, c.verifyany,
d.data AS memberstatus
FROM {customcert} c
JOIN {customcert_issues} ci ON c.id = ci.customcertid
JOIN {course} co ON c.course = co.id
JOIN {user} u ON ci.userid = u.id
LEFT JOIN (
SELECT d.userid, d.data
FROM {user_info_data} d
JOIN {user_info_field} f ON f.id = d.fieldid AND f.shortname = 'member_status'
) d ON d.userid = u.id
WHERE ci.code = :code";
I have two queries that i need to combine into one query. The problem is they are using the same columns in where clause depending on what i need to fetch.
Query 1
SELECT c.fullname, COUNT( DISTINCT sst.id ) AS 'Liczba rozpoczetych szkolen'
FROM mdl_course c
INNER JOIN mdl_scorm s ON s.course = c.id
INNER JOIN mdl_scorm_scoes_track sst ON s.id = sst.scormid
INNER JOIN mdl_user u ON u.id = sst.userid
WHERE sst.element = 'x.start.time' AND u.deleted =0
GROUP BY c.fullname ORDER BY `Liczba rozpoczetych szkolen` ASC
Query 2
SELECT c.fullname, COUNT(DISTINCT sst.userid ) AS 'Liczba_ukonczonych_szkolen'
FROM mdl_course c
INNER JOIN mdl_scorm s ON s.course=c.id
INNER JOIN mdl_scorm_scoes_track sst ON s.id = sst.scormid
INNER JOIN mdl_user u ON sst.userid=u.id
where `element`='cmi.core.score.raw' and `value` = 100 and u.deleted = 0
GROUP BY c.fullname ORDER BY `Liczba_ukonczonych_szkolen` DESC
They are depending on the same column named 'element'.
How i can display the result as
fullname Liczba rozpoczetych szkolen Liczba_ukonczonych_szkolen
A1 34 4
A2 5 3
A3 34 33
I've came up with this one, whitch works. Thanks for advice #HoneyBadger
SELECT t1.fullname, t1.Liczba_rozpoczetych_szkolen, t2.Liczba_ukonczonych_szkolen,
round(((t2.Liczba_ukonczonych_szkolen /t1.Liczba_rozpoczetych_szkolen)*100),2) as procentowo
FROM
(SELECT c.fullname, COUNT( DISTINCT sst.id ) AS Liczba_rozpoczetych_szkolen
FROM mdl_course c
INNER JOIN mdl_scorm s ON s.course = c.id
INNER JOIN mdl_scorm_scoes_track sst ON s.id = sst.scormid
INNER JOIN mdl_user u ON u.id = sst.userid
WHERE sst.element = 'x.start.time' AND u.deleted =0
GROUP BY c.fullname ) AS t1,
(SELECT c.fullname, COUNT(DISTINCT sst.userid ) AS Liczba_ukonczonych_szkolen
FROM mdl_course c
INNER JOIN mdl_scorm s ON s.course=c.id
INNER JOIN mdl_scorm_scoes_track sst ON s.id = sst.scormid
left join mdl_user u ON sst.userid=u.id
where `element`='cmi.core.score.raw' and `value` = 100 and u.deleted = 0
GROUP BY c.fullname) as t2
WHERE t1.fullname = t2.fullname
You can join them together like this:
SELECT COALESCE(R.fullname, U.fullname) AS fullname
, COALESCE(R.Liczba_rozpoczetych_szkolen, 0) AS Liczba_rozpoczetych_szkolen
, COALESCE(R.Liczba_ukonczonych_szkolen, 0) AS Liczba_ukonczonych_szkolen
FROM (
SELECT c.fullname
, COUNT( DISTINCT sst.id ) AS Liczba_rozpoczetych_szkolen
FROM mdl_course c
INNER JOIN mdl_scorm s
ON s.course = c.id
INNER JOIN mdl_scorm_scoes_track sst
ON s.id = sst.scormid
INNER JOIN mdl_user u
ON u.id = sst.userid
WHERE sst.element = 'x.start.time'
AND u.deleted =0
GROUP BY c.fullname
) AS R
FULL JOIN (
SELECT c.fullname
, COUNT(DISTINCT sst.userid ) AS Liczba_ukonczonych_szkolen
FROM mdl_course c
INNER JOIN mdl_scorm s
ON s.course=c.id
INNER JOIN mdl_scorm_scoes_track sst
ON s.id = sst.scormid
INNER JOIN mdl_user u
ON sst.userid=u.id
where `element`='cmi.core.score.raw'
AND `value` = 100
AND u.deleted = 0
GROUP BY c.fullname
) AS U
ON R.fullname = U.fullname
Try the query with the ORed predicates and extra filtering with CASE in the SELECT list. Kind of
SELECT c.fullname, COUNT(DISTINCT CASE WHEN sst.element = 'x.start.time' THEN sst.id END) AS 'Liczba rozpoczetych szkolen'
, COUNT(DISTINCT CASE WHEN sst.element = 'cmi.core.score.raw' and `value` = 100 THEN sst.userid END) AS 'Liczba_ukonczonych_szkolen'
FROM mdl_course c
INNER JOIN mdl_scorm s ON s.course = c.id
INNER JOIN mdl_scorm_scoes_track sst ON s.id = sst.scormid
INNER JOIN mdl_user u ON u.id = sst.userid
WHERE sst.element = IN( 'x.start.time', 'cmi.core.score.raw') AND u.deleted =0
GROUP BY c.fullname ORDER BY `Liczba rozpoczetych szkolen` ASC
Could someone please change the following query to work on postgres?
SELECT
user2.id AS ID,
ul.timeaccess,
user2.firstname AS Firstname,
user2.lastname AS Lastname,
user2.email AS Email,
user2.username AS IDNumber,
user2.institution AS Institution,
IF (user2.lastaccess = 0,'never',
DATE_FORMAT(FROM_UNIXTIME(user2.lastaccess),'%Y-%m-%d')) AS dLastAccess
,(SELECT DATE_FORMAT(FROM_UNIXTIME(timeaccess),'%Y-%m-%d') FROM mdl_user_lastaccess WHERE userid=user2.id AND courseid=c.id) AS CourseLastAccess
,(SELECT r.name
FROM mdl_user_enrolments AS uenrol
JOIN mdl_enrol AS e ON e.id = uenrol.enrolid
JOIN mdl_role AS r ON e.id = r.id
WHERE uenrol.userid=user2.id AND e.courseid = c.id) AS RoleName
FROM mdl_user_enrolments AS ue
JOIN mdl_enrol AS e ON e.id = ue.enrolid
JOIN mdl_course AS c ON c.id = e.courseid
JOIN mdl_user AS user2 ON user2 .id = ue.userid
LEFT JOIN mdl_user_lastaccess AS ul ON ul.userid = user2.id
WHERE c.id=14 AND ue.userid NOT IN (SELECT qa.userid FROM mdl_quiz_attempts AS qa
JOIN mdl_quiz AS q ON qa.quiz = q.id
JOIN mdl_course AS c ON q.course = c.id
WHERE c.id = 14 AND q.name LIKE '%quiz name goes here%')
It is for Moodle
i understand that it has to go to_char etc but don't know how to change it
Thanks in advance
SELECT
user2.id AS "ID",
ul.timeaccess,
user2.firstname AS "Firstname",
user2.lastname AS "Lastname",
user2.email AS "Email",
user2.username AS "IDNumber",
user2.institution AS "Institution",
(CASE WHEN user2.lastaccess = 0 THEN'never' END ||
to_char(to_timestamp(user2.lastaccess)::date,'YYYY-MM-DD')) AS "dLastAccess"
,(SELECT to_char(to_timestamp(timeaccess)::date,'YYYY-MM-DD') FROM mdl_user_lastaccess WHERE userid=user2.id AND courseid=c.id) AS "CourseLastAccess"
,(SELECT r.name
FROM mdl_user_enrolments AS uenrol
JOIN mdl_enrol AS e ON e.id = uenrol.enrolid
JOIN mdl_role AS r ON e.id = r.id
WHERE uenrol.userid=user2.id AND e.courseid = c.id) AS "RoleName"
FROM mdl_user_enrolments AS ue
JOIN mdl_enrol AS e ON e.id = ue.enrolid
JOIN mdl_course AS c ON c.id = e.courseid
JOIN mdl_user AS user2 ON user2 .id = ue.userid
LEFT JOIN mdl_user_lastaccess AS ul ON ul.userid = user2.id
WHERE c.id=14 AND ue.userid NOT IN (SELECT qa.userid FROM mdl_quiz_attempts AS qa
JOIN mdl_quiz AS q ON qa.quiz = q.id
JOIN mdl_course AS c ON q.course = c.id
WHERE c.id = 14 AND q.name LIKE '%quiz name goes here%')
Hey I tried.
FROM_UNIXTIME -is equivalent to to_timestamp on postgres.
IF ELSE are CASE WHEN in postgres.
to_char - if you want to format the date use this.
Have a look at: Data Type Formatting Functions on Postgres docs.
Use to_char(date, 'YYYY-MM-DD')
For example:
select to_char('20170501'::date, 'YYYY-MM-DD')
Returns:
2017-05-01
Check it here: http://rextester.com/JDZA16474
I need an SQL query that will give me all users enrolled to a course in the last 90 days that are not suspended.
I have done some searching and found this:
SELECT DISTINCT u.id AS userid, c.id AS courseid
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid AND ct.contextlevel = 50
JOIN mdl_course c ON c.id = ct.instanceid AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid AND r.shortname = 'student'
WHERE e.status = 0 AND u.suspended = 0 AND u.deleted = 0
AND (ue.timeend = 0 OR ue.timeend > NOW()) AND ue.status = 0
I can return results from a specific course by adding AND courseid = 11 to the end of the query, but i'm still struggling with the date range.
I've tried using:
AND ue.timecreated BETWEEN NOW() - INTERVAL 90 DAY AND NOW()
but that is returning no results i even tried to add 2000 day range and it returns nothing
this is my current modified query:
SELECT DISTINCT u.id AS userid, c.id AS courseid, DATE_FORMAT(ue.timecreated, '%m/%d/%Y')
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid
AND ct.contextlevel =50
JOIN mdl_course c ON c.id = ct.instanceid
AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid
AND r.shortname = 'student'
WHERE e.status =0
AND u.suspended =0
AND u.deleted =0
AND (
ue.timeend =0
OR ue.timeend > NOW()
)
AND ue.status =0
AND ue.timecreated BETWEEN NOW() - INTERVAL 1200 DAY AND NOW()
AND courseid = 11
And that return nothing, as soon as I remove the second-last line that contains the date range I receive all the results inside course id 11.
Basically I need:
A list of all users that are enrolled in to a specific course in the last 90 days that is not suspended or deleted.
Results would be something like:
course id: 20
user id: 200, 533, 221, 22, 356
the solution is here:
SELECT DISTINCT u.id AS userid, c.id AS courseid, DATE_FORMAT(FROM_UNIXTIME(ue.timecreated),'%m/%d/%Y') AS timecreated
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid
AND ct.contextlevel =50
JOIN mdl_course c ON c.id = ct.instanceid
AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid
AND r.shortname = 'student'
WHERE e.status =0
AND u.suspended =0
AND u.deleted =0
AND (
ue.timeend =0
OR ue.timeend > NOW( )
)
AND ue.status =0
AND courseid =11
AND FROM_UNIXTIME(ue.timecreated) BETWEEN CURDATE() - INTERVAL 90 DAY AND CURDATE()
The times in Moodle are stored as integers and are a UTC unix timestamp. So the date functions in MySql won't work - unless they are converted using FROM_UNIXTIME().
If you want all users enrolled, not just students, then this is simpler.
SELECT ue.id, e.courseid, ue.userid, e.enrol AS enrolmethod, FROM_UNIXTIME(ue.timecreated)
FROM mdl_user_enrolments ue
JOIN mdl_enrol e ON e.id = ue.enrolid AND e.status = 0
JOIN mdl_user u ON u.id = ue.userid AND u.deleted = 0 AND u.suspended = 0
WHERE ue.timecreated >= 90 * 24 * 60 * 60 AND ue.status = 0
A user could be enrolled using more than one method though. So if you just want the userid and courseid then use a group by rather than a distinct.
SELECT CONCAT(e.courseid, '_', ue.userid) AS uniqueid, e.courseid, ue.userid, FROM_UNIXTIME(MAX(ue.timecreated))
FROM mdl_user_enrolments ue
JOIN mdl_enrol e ON e.id = ue.enrolid AND e.status = 0
JOIN mdl_user u ON u.id = ue.userid AND u.deleted = 0 AND u.suspended = 0
WHERE ue.status = 0
GROUP BY e.courseid, ue.userid
HAVING MAX(ue.timecreated) >= 90 * 24 * 60 * 60
we're running this query in moodle database:
SELECT l.*,
MAX(l.time) as time,cat.id as catid, cat.name as catname,c.id as courseid,
c.fullname as coursename,
m.name as module,
r.revision as revision,
r.name as resourcename,
sco.name as scormname,
glo.name as glossaryname,
qui.name as quizname
FROM {log} l
INNER JOIN {user} u ON l.userid = u.id
INNER JOIN {course} c ON l.course = c.id
INNER JOIN {course_categories} cat ON c.category = cat.id
INNER JOIN {course_modules} cm ON l.cmid = cm.id
INNER JOIN {modules} m ON cm.module = m.id
LEFT JOIN {resource} r ON cm.instance = r.id and l.module = "resource"
LEFT JOIN {scorm} sco ON cm.instance = sco.id and l.module = "scorm"
LEFT JOIN {glossary} glo ON cm.instance = glo.id and l.module = "glossary"
LEFT JOIN {quiz} qui ON cm.instance = qui.id and l.module = "quiz"
WHERE LOWER(l.action) LIKE LOWER(:modaction) COLLATE utf8_bin AND l.userid = :userid
GROUP BY l.cmid
ORDER BY MAX(l.time) DESC
and i would like something like this:
SELECT l.*,
MAX(l.time) as time,cat.id as catid, cat.name as catname,c.id as courseid,
c.fullname as coursename,
m.name as module,
r.revision as revision,
r.name as resourcename
FROM {log} l
INNER JOIN {user} u ON l.userid = u.id
INNER JOIN {course} c ON l.course = c.id
INNER JOIN {course_categories} cat ON c.category = cat.id
INNER JOIN {course_modules} cm ON l.cmid = cm.id
INNER JOIN {modules} m ON cm.module = m.id
INNER JOIN (
SELECT * {resource} re WHERE cm.instance = r.id OR
SELECT * {scorm} sco WHERE cm.instance = sco.id OR
SELECT * {glossary} WHERE ON cm.instance = glo.id OR
SELECT * {quiz} qui WHERE cm.instance = qui.id OR
) as r
WHERE LOWER(l.action) LIKE LOWER(:modaction) COLLATE utf8_bin AND l.userid = :userid
GROUP BY l.cmid
ORDER BY MAX(l.time) DESC
Results return NULL values in "resource" names (resourcename, scormname, glossaryname or quizname) and only one valid "resource" name. I render results depending on if result is not null.
But i would like to avoid "filter" by not null result in resourcename, scormname, glossaryname and quizname using PHP.
Thanks!
Something like this maybe - use a union
SELECT l.cmid,
MAX(l.time) as logtime,
cat.id as catid,
cat.name as catname,
c.id as courseid,
c.fullname as coursename,
mods.module,
mods.revision,
mods.name as modname
FROM mdl_log l
JOIN mdl_user u ON l.userid = u.id
JOIN mdl_course c ON l.course = c.id
JOIN mdl_course_categories cat ON c.category = cat.id
JOIN (
SELECT cm.id AS cmid, m.name AS module, r.name, r.revision
FROM mdl_course_modules cm
JOIN mdl_modules m ON cm.module = m.id AND m.name = 'resource'
JOIN mdl_resource r ON r.id = cm.instance
UNION
SELECT cm.id AS cmid, m.name as modulentype, s.name, NULL AS revision
FROM mdl_course_modules cm
JOIN mdl_modules m ON cm.module = m.id AND m.name = 'scorm'
JOIN mdl_scorm s ON s.id = cm.instance
UNION
SELECT cm.id AS cmid, m.name as modulentype, g.name, NULL AS revision
FROM mdl_course_modules cm
JOIN mdl_modules m ON cm.module = m.id AND m.name = 'glossary'
JOIN mdl_glossary g ON g.id = cm.instance
UNION
SELECT cm.id AS cmid, m.name as modulentype, q.name, NULL AS revision
FROM mdl_course_modules cm
JOIN mdl_modules m ON cm.module = m.id AND m.name = 'quiz'
JOIN mdl_quiz q ON q.id = cm.instance
) mods ON mods.cmid = l.cmid AND mods.module = l.module
WHERE l.module IN ('resource', 'scorm', 'glossary', 'quiz')
GROUP BY l.cmid
ORDER BY 1 DESC