Moodle 上类(class)注册的 SQL 查询

标签 sql database moodle

我一直在寻找合适的 SQL 查询来检索在 Moodle 上注册某门类(class)的所有学生,或某位学生注册的所有类(class)。

我从网上找了几个解决方案,大部分建议加入这些表:
上下文、role_assignments、类(class)、用户、角色

但是当我查看数据库时,我发现有一个名为user_enrolments 的表,在我看来,我可以通过连接以下表来获得结果:
user_enrolments, user, course, enrol

例如,

SELECT u.id, c.id
FROM mdl_user u
INNER JOIN mdl_user_enrolments ue ON ue.userid = u.id
INNER JOIN mdl_enrol e ON e.id = ue.enrolid
INNER JOIN mdl_course c ON e.courseid = c.id

SELECT u.id, c.id
FROM mdl_user u
INNER JOIN mdl_role_assignments ra ON ra.userid = u.id
INNER JOIN mdl_context ct ON ct.id = ra.contextid
INNER JOIN mdl_course c ON c.id = ct.instanceid
INNER JOIN mdl_role r ON r.id = ra.roleid
WHERE r.id = 5

(其中 5 是角色 student 的 ID)

这 2 个查询为我提供了相同 的结果集。 (仅在一小部分数据上测试)

所以我想问一下这两种方式有什么区别?
感谢您提前提供任何帮助。

最佳答案

第一个查询为您提供了已注册类(class)的用户列表,以及他们分配给他们的任何角色(可能注册了类(class)但根本没有分配任何角色)。

第二个查询显示在类(class)级别分配了角色 5 的所有用户。有可能(虽然不常见)在类(class)级别分配角色,但实际上并未注册类(class)本身。

然而,这两个查询都是有缺陷的。

如果用户通过多种注册方法注册了类(class)(不常见,但有可能),第一个查询可能会返回重复的结果。它还没有考虑以下因素:

  • 可以在站点级别禁用注册插件
  • 可以在类(class)级别禁用注册插件(检查“e.status = 0”以仅查找事件的注册插件)
  • 注册可能是有时间限制的——用户的注册可能已经过期(检查“ue.timeend = 0 OR ue.timeend > NOW()”以仅查找未过期的注册)

第二个查询假设学生角色是 id 5(并且没有其他基于学生角色的角色在使用中)。我通常会使用额外的查询来检查表“mdl_role”中“学生”角色的 ID,然后使用该值,或者将最后几行更改为以下内容:

在 r.id = ra.roleid 和 r.shortname = 'student' 上加入 mdl_role r。

第二个查询也无法检查“上下文级别”——可能有多个上下文具有相同的实例 ID(因为可能有类(class) ID 5、类(class)类别 ID 5、用户 ID 5 等。 ) - 因此您需要检查找到的上下文是否是“类(class)”上下文 (contextlevel = 50)。

既不查询检查已暂停的用户,也不检查已删除的用户(尽管对于已删除的用户,他们应该在删除时自动从所有类(class)中取消注册)。

一个完全完整的解决方案(在大多数情况下可能过于复杂)会将两个查询组合在一起以检查用户是否已注册并分配了学生角色并且没有被暂停:

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 > UNIX_TIMESTAMP(NOW())) AND ue.status = 0

(请注意,我没有仔细检查该查询 - 它运行,但您需要仔细交叉引用实际注册以检查我没有遗漏任何内容)。

关于Moodle 上类(class)注册的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22161606/

相关文章:

sql - Oracle PL/SQL 上年和上月

MySQL - 从其他表计算排名

sql - 触发器 Oracle 中插入行的值

mysql - 如何编写一个 SQL 查询来获取一个列中的 ID,而该列中的所有必需数据都在其他列中?

moodle - 如何从moodle数据库输出HTML表格中的记录?

MYSQL查询错误

mysql - 如何修改这个子查询以使其更具体

php - 具有角色、角色特定字段的 MySQL 用户?

php - 获取 JSON 格式的 Moodle 数据

dotNetNuke/Moodle 集成