コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- 央之 國松 の投稿
返信数: 6

お世話になっております。


現在、Moodle上にあるコースの一覧と、各コースの登録受講者数とそのうちの完了者数を出力したいと考えています。
Moodleのレポート機能ではできそうにありませんでしたので、DBからSQL文で直接抽出することを検討しています。

下記のSQL文を試したところ、コース一覧は出力できますが、完了者数が合計されてしまい、すべて同じ数字になってしまいました。(画像の参照をお願いします。)
完了者数をコース別に抽出するには、SQL文をどのように修正すればよいか、ご教授していただけますでしょうか。

SELECT DISTINCT c.fullname AS CourseName,
       ( SELECT COUNT(u.id)
         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 EXIST (
                     SELECT *
                     FROM mdl_course_completion_crit_compl
                     WHERE userid = u.id
                     AND course = c.id
                   )
       ) AS NumberOfCompleters
FROM mdl_course c

このSQL文で出力される結果は以下の画像のようになってしまいます。
SQL文の出力結果


以上です。よろしくお願いいたします。

央之 國松 への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators

以下のようなSQL文ではいかがでしょうか。

SELECT cs.fullname AS 'Course Name'
       ,rl.shortname AS 'Role'
       ,COUNT(u.id) AS 'User count'
       ,COUNT(cc.timecompleted > 0) AS 'Completed'
FROM mdl_role_assignments AS ra
   JOIN mdl_user AS u on ra.userid = u.id
   JOIN mdl_role AS rl on ra.roleid = rl.id
   JOIN mdl_context AS ctx on ra.contextid = ctx.id
   JOIN mdl_course AS cs on ctx.instanceid = cs.id
   JOIN mdl_course_completions AS cc on ra.userid = cc.userid AND cs.id = cc.course
WHERE rl.shortname = 'student'
GROUP BY cs.fullname, rl.shortname
評点平均: お役立ち度: ★★★★★★★ (1)
Mitsuhiro Yoshida への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- 央之 國松 の投稿

ありがとうございます。

教えていただいたSQL文を実行したところ、画像のようにひとつのコースのみが表示されました。


このコースにおける受講者数、完了者数は正しいものとなっています。
その他のコース(受講者数や完了者数が0のものも含む)も一覧として出力したいと考えています。

央之 國松 への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators

大変失礼しました。
以下のようなSQL文ではいかがでしょうか

SELECT cs.fullname AS 'Course Name'
       ,rl.shortname AS 'Role'
       ,COUNT(u.id) AS 'User count'
       ,COUNT(cc.timecompleted > 0) AS 'Completed'
FROM mdl_role_assignments AS ra
   LEFT JOIN mdl_user AS u on ra.userid = u.id
   LEFT JOIN mdl_role AS rl on ra.roleid = rl.id
   LEFT JOIN mdl_context AS ctx on ra.contextid = ctx.id
   LEFT JOIN mdl_course AS cs on ctx.instanceid = cs.id
   LEFT JOIN mdl_course_completions AS cc on ra.userid = cc.userid AND cs.id = cc.course
WHERE rl.shortname = 'student'
GROUP BY cs.fullname, rl.shortname
添付 phpMyAdmin.png
評点平均: お役立ち度: ★★★★★★★ (2)
Mitsuhiro Yoshida への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- 央之 國松 の投稿
お世話になっております。

ご教示いただいたSQL文の結果は以下のようになりました。


当初予定していた結果を出力することができました。ありがとうございます。

以下はSQL文に対しての質問になるのですが、
①「COUNT(cc.timecompleted > 0) AS 'Completed」については、「cc.timecompleted > 0」で、「完了日時が0より大きいものをCOUNTしている=完了日時が記録されている=コースを完了している数をCOUNTしている」という理解でよろしいでしょうか?
②「受講者数(student)がいないコースは、User countがNULLとなり表示されない」という理解でよろしいでしょうか?

央之 國松 への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators

> ①「COUNT(cc.timecompleted > 0) AS 'Completed」については、「cc.timecompleted > 0」で、「完了日時が0より大きいものをCOUNTしている=完了日時が記録されている=コースを完了している数をCOUNTしている」という理解でよろしいでしょうか?

はい、そうです。

>②「受講者数(student)がいないコースは、User countがNULLとなり表示されない」という理解でよろしいでしょうか?

はい、そうです。
編集権限のある教師 (editingteacher) または教師 (teacher) のみ登録されて受講者(student)がいないコースも表示したい場合、「WHERE rl.shortname = 'student'」を取り除いた以下のSQL文をお使いください。

SELECT cs.fullname AS 'Course Name'
       ,rl.shortname AS 'Role'
       ,COUNT(u.id) AS 'User count'
       ,COUNT(cc.timecompleted > 0) AS 'Completed'
FROM mdl_role_assignments AS ra
   LEFT JOIN mdl_user AS u on ra.userid = u.id
   LEFT JOIN mdl_role AS rl on ra.roleid = rl.id
   LEFT JOIN mdl_context AS ctx on ra.contextid = ctx.id
   LEFT JOIN mdl_course AS cs on ctx.instanceid = cs.id
   LEFT JOIN mdl_course_completions AS cc on ra.userid = cc.userid AND cs.id = cc.course
GROUP BY cs.fullname, rl.shortname
添付 course_completed.png
評点平均: お役立ち度: ★★★★★★★ (1)
Mitsuhiro Yoshida への返信

Re: コースの一覧と、各コースの受講者数、完了者数を抽出するSQLについて

- 央之 國松 の投稿
お世話になっております。

ご回答ありがとうございます。
「WHERE rl.shortname = 'student'」を除いた場合、全コース抽出されることを確認しました。
望んだレポート結果を出力することができそうです。
ありがとうございました。