0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MoodleのAd-hoc database queriesで作る管理者向け受講完了レポート

0
Posted at

はじめに

Moodleを運用していると、こんな場面に出くわすことがあります。

「誰がどのコースをどこまで進んでいるか、一覧で確認したい」
「小テストは合格しているのか、修了証は発行されたのかも含めて把握したい」

標準のレポート機能を覗いてみると、コース別・ユーザー別にバラバラになっていて、「全員分を横断して一覧にするには……?」と詰まってしまうんですよね。

この記事では、Ad-hoc database queries というプラグインを使って、以下のような管理者向けレポートをMoodle上で作る手順を紹介します。

ユーザー名 氏名 コース名 登録日 経過日数 最終ログイン 種別 アクティビティ名 完了状態 完了日 修了証
yamada 山田太郎 情報セキュリティ基礎 2026-04-01 47 2026-05-10 小テスト 確認テスト第1回 合格で完了 2026-04-15
yamada 山田太郎 情報セキュリティ基礎 2026-04-01 47 2026-05-10 ファイル テキストPDF 完了 2026-04-10
yamada 山田太郎 情報セキュリティ基礎 2026-04-01 47 2026-05-10 修了証 修了証 完了 2026-04-20 発行済み

動作確認はMoodle 4.5(セルフホスト)で行っています。


こんなときに使える

1. 月次の受講進捗報告

人事・研修担当者がマネージャーや経営層に対して月次で受講状況を報告するケース。「誰がどのコースをどこまで進んでいるか」をまとめた資料が必要になります。Moodle標準のレポートでは複数コース・複数ユーザーを横断した一覧が作りにくく、毎回手作業でデータをつなぎ合わせているケースも少なくないんじゃないでしょうか。

2. 全員受講が義務付けられている研修の管理

職場のハラスメント防止研修や情報セキュリティ教育など、コンプライアンス系の研修は「誰が未受講か」「小テストで合格しているか」「修了証が発行されているか」を一目で把握したいですよね。

3. 顧客企業への受講報告

研修サービスを提供している事業者が、クライアント企業に受講状況を報告するケース。「〇〇社の受講者全員の進捗をまとめてほしい」という依頼に対して、CSVで素早く出せると話が早いです。

4. コース改善のためのデータ分析

「どのアクティビティで多くの学習者が止まっているか」「小テストの合格率が低いモジュールはどれか」を把握して、コース設計の改善に活かすケース。こういう分析、意外とMoodle標準UIだとやりにくいんですよね。

5. eラーニング導入効果の検証

Moodleを導入してどの程度活用されているかを経営層に示すため、全体の完了率・ログイン頻度などをまとめたレポートが必要になるケース。

標準レポート・レポートビルダーでは作れない理由

「Moodleに最初からレポート機能がついているんじゃないの?」と思われるかもしれません。確かにあります。ただ、今回やりたいことには足りない部分があります。

Moodle標準のレポート機能

  • 活動完了レポート(コース内):1コース内のアクティビティ別完了状況は確認できますが、複数コースをまたいだ集計はできません
  • コース完了レポート:コース単位の完了状況のみで、アクティビティ別の詳細は出ません
  • ログレポート:操作履歴は見られますが、完了状況との紐付けはできません

Moodle Workplaceのレポートビルダー

Moodle Workplaceには高機能なレポートビルダーが搭載されていて、「コース参加者」「発行された認定書」「プログラム」などのデータソースが使えます。ただし 「活動完了」(アクティビティ単位の完了状況)はデータソースとして提供されていません。コース全体の進捗率(%)は取れますが、「小テストAは合格、PDFは未閲覧」といったアクティビティ単位の詳細はレポートビルダーでは出せないんです。

つまり、「誰がどのアクティビティをどんな状態で完了しているか」を1画面で出す方法が、標準機能にはないというのが現状です。

Ad-hoc database queriesを選ぶ理由

プラグインの概要

Ad-hoc database queriesreport_customsql)は、The Open University(英国)が開発・公開しているMoodleプラグインです。管理者がSQLクエリを登録しておくことで、Moodle管理画面から直接データベースに対してレポートを実行できます。

ad-hoc database queries

選ぶ理由

自由度が高い:レポートビルダーのUIで選べる列に限定されず、JOINやCASE文を使って必要な情報を自由に組み合わせられます。

無料で使える:OSSプラグインなので追加コストはかかりません。IntelliBoardなどの商用SaaSと比べると、ランニングコストの差は大きいです。

CSV出力に対応:レポート結果をCSVでダウンロードできるため、ExcelやGoogleスプレッドシートでの加工・共有が楽です。

Moodle 4.5・5.0対応:執筆時点(2026年5月)で最新のMoodleバージョンに対応しています。

できないこと

一方で、以下はこのプラグインではできません。

  • INSERT・UPDATE・DELETEなどの書き込みクエリ(SELECTのみ)
  • グラフ・チャートの描画
  • リアルタイムダッシュボード
  • ドリルダウン表示(行をクリックして詳細に入る、など)

あくまで「SQLで取ってきたデータをテーブル表示 + CSVダウンロード」というシンプルなツールです。それで十分なユースケースも多いですし、今回の目的にはちょうどよいです。
もし、結果をビジュアルに表現したいというニーズがある場合は、CSVで書き出しデータをMicrosoft Power BIなどのBIツールに読み込んで加工することを検討した方が良いでしょう。

インストール方法

前提条件

  • Moodle 4.x または 5.x(セルフホスト環境)
  • サイト管理者権限

Moodle Workplaceをお使いの方へ:SaaS版・セルフホスト版ともにAd-hoc database queriesは利用可能です。ただし修了証など一部のテーブル構造が標準Moodleと異なるため、SQLの書き換えが必要な箇所があります。詳細は記事末尾の「Moodle Workplaceを使う場合の補足」を参照してください。

方法A:Moodle管理画面からインストール

  1. 「サイト管理」 > 「プラグイン」 > 「プラグイン」をインストールする
  2. Moodle.org からzipをダウンロード
  3. zipファイルをアップロードしてインストール

方法B:サーバーに直接配置

cd /path/to/moodle/report
git clone https://github.com/timhunt/moodle-report_customsql.git customsql

その後、サイト管理 > 通知 にアクセスしてアップグレードを実行します。

インストール後に「サイト管理」 > 「レポート」のメニューに「アドホックデータベースクエリ」が表示されれば完了です。

サイト管理→レポートのメニューに「アドホックデータベースクエリ」が表示されている画面

基本的な使い方

クエリの作成

「サイト管理」>「レポート」> 「アドホックデータベースクエリ」を開いて、「新しいクエリを追加する」をクリックします。カテゴリ・クエリ名・説明・SQLを入力して保存するだけです。

アドホックデータベースクエリのトップ画面(「クエリを追加する」ボタンが見えている状態

クエリ追加フォームの画面(カテゴリ・クエリ名・説明・クエリSQL欄が並んでいる状態)

SQLを書くときの2つのルール

このプラグインには、通常のSQLと違う点が2つあります。これを知らないとエラーが出るので最初に押さえておきましょう。

① テーブル名は {} で囲む

Moodleのテーブル名にはプレフィックス(デフォルトは mdl_)が付いています。プラグインがプレフィックスを自動補完するので、クエリ内では {} で囲んだプレフィックスなしの名前を使います。

-- ❌ これはエラーになる
SELECT * FROM mdl_user

-- ✅ こう書く
SELECT * FROM {user}

② LIMIT句は書かない

プラグインが自動でページング用のLIMITを付加するため、クエリ内にLIMITを書くとSQL構文エラーになります。

-- ❌ エラーになる
SELECT * FROM {user} LIMIT 10

-- ✅ LIMITなしで書く
SELECT * FROM {user}

動作確認用のシンプルなクエリ

まずこれで動くか確認してみてください。

SELECT
    u.username   AS ユーザー名,
    u.lastname   AS ,
    u.firstname  AS ,
    u.email      AS メールアドレス,
    FROM_UNIXTIME(u.lastlogin, '%Y-%m-%d') AS 最終ログイン日
FROM {user} u
WHERE u.deleted = 0
  AND u.id > 1
ORDER BY u.lastname, u.firstname

こんな結果が出たら成功です。
シンプルなクエリのテスト

目的のレポートを作る

使うテーブルの整理

今回のレポートで使うテーブルは以下のとおりです。

テーブル 用途
{user} ユーザー情報
{user_enrolments} コース登録情報
{enrol} 登録方法
{course} コース情報
{course_modules} コース内のアクティビティ
{modules} アクティビティの種別(quiz, resourceなど)
{course_modules_completion} アクティビティ別完了状況
{quiz} / {resource} など アクティビティの名称取得
{customcert_issues} カスタム修了証の発行状況(mod_customcert プラグインが必要)

completionstateの値について

{course_modules_completion} テーブルの completionstate カラムは以下の値を取ります。

意味
NULL(レコードなし) 未着手
0 未完了(開始したが条件未達)
1 完了
2 合格で完了(小テストなどで合格点に達した)
3 不合格

完成版SQL

SELECT
    u.username                      AS ユーザー名,
    CONCAT(u.lastname, u.firstname) AS 氏名,
    c.fullname                      AS コース名,
    FROM_UNIXTIME(ue.timecreated, '%Y-%m-%d') AS コース登録日,
    DATEDIFF(NOW(), FROM_UNIXTIME(ue.timecreated)) AS 経過日数,
    CASE WHEN u.lastlogin > 0
        THEN FROM_UNIXTIME(u.lastlogin, '%Y-%m-%d')
        ELSE ''
    END                             AS 最終ログイン日,
    CASE m.name
        WHEN 'quiz'       THEN '小テスト'
        WHEN 'resource'   THEN 'ファイル'
        WHEN 'url'        THEN 'URL'
        WHEN 'page'       THEN 'ページ'
        WHEN 'feedback'   THEN 'アンケート'
        WHEN 'customcert' THEN '修了証'
        WHEN 'assign'     THEN '課題'
        ELSE m.name
    END                             AS 種別,
    COALESCE(
        q.name,
        r.name,
        p.name,
        f.name,
        fb.name,
        assign.name,
        scorm.name,
        url.name,
        cc.name
    )                               AS アクティビティ名,
    CASE cmc.completionstate
        WHEN 0 THEN '未完了'
        WHEN 1 THEN '完了'
        WHEN 2 THEN '合格で完了'
        WHEN 3 THEN '不合格'
        ELSE '未着手'
    END                             AS 完了状態,
    CASE WHEN cmc.timemodified > 0
        THEN FROM_UNIXTIME(cmc.timemodified, '%Y-%m-%d')
        ELSE ''
    END                             AS 完了日,
    CASE WHEN ci.id IS NOT NULL
        THEN '発行済み'
        ELSE ''
    END                             AS 修了証
FROM {user} u
JOIN {user_enrolments} ue ON ue.userid = u.id
JOIN {enrol} e            ON e.id = ue.enrolid
JOIN {course} c           ON c.id = e.courseid
JOIN {course_modules} cm  ON cm.course = c.id AND cm.completion > 0
JOIN {modules} m          ON m.id = cm.module
LEFT JOIN {course_modules_completion} cmc
    ON cmc.coursemoduleid = cm.id AND cmc.userid = u.id
LEFT JOIN {quiz}       q      ON m.name = 'quiz'       AND q.id = cm.instance
LEFT JOIN {resource}   r      ON m.name = 'resource'   AND r.id = cm.instance
LEFT JOIN {page}       p      ON m.name = 'page'       AND p.id = cm.instance
LEFT JOIN {forum}      f      ON m.name = 'forum'      AND f.id = cm.instance
LEFT JOIN {feedback}   fb     ON m.name = 'feedback'   AND fb.id = cm.instance
LEFT JOIN {assign}     assign ON m.name = 'assign'     AND assign.id = cm.instance
LEFT JOIN {scorm}      scorm  ON m.name = 'scorm'      AND scorm.id = cm.instance
LEFT JOIN {url}        url    ON m.name = 'url'        AND url.id = cm.instance
LEFT JOIN {customcert} cc     ON m.name = 'customcert' AND cc.id = cm.instance
LEFT JOIN {customcert_issues} ci
    ON ci.customcertid = cm.instance
    AND ci.userid = u.id
    AND m.name = 'customcert'
WHERE u.deleted = 0
  AND u.id > 1
  AND u.username != 'admin'
ORDER BY u.username, c.fullname, cm.section, cm.id

完成版SQLを実行した結果画面

SQLのポイント解説

完了条件が設定されたアクティビティだけを対象にする

JOIN {course_modules} cm ON cm.course = c.id AND cm.completion > 0

cm.completion > 0 により、Moodleの活動完了設定で「完了条件」が設定されているアクティビティのみを対象にします。完了条件が未設定のアクティビティは除外されます。

未着手のユーザーも表示する

LEFT JOIN {course_modules_completion} cmc
    ON cmc.coursemoduleid = cm.id AND cmc.userid = u.id

LEFT JOIN を使うことで、まだアクティビティを開始していない(cmc にレコードがない)ユーザーも NULL → '未着手' として表示できます。コース登録はしたが何もしていない人もちゃんと出てきます。

アクティビティ名の取得

Moodleはアクティビティの種別ごとに別テーブルを持っています({quiz}{resource}{page} など)。それぞれをLEFT JOINして、COALESCE で最初に見つかった値をアクティビティ名として使います。

修了証アクティビティの注意点

このSQLの修了証機能は Custom certificatemod_customcert)プラグインを使用しています。Moodle標準には修了証機能が含まれていないため、事前に Moodle.org からインストールしておく必要があります。

customcert(カスタム修了証)アクティビティがレポートに表示されるには、アクティビティの完了条件に「証明書を受け取ったら完了とみなす」を設定する必要があります。設定がないと cm.completion = 0 となり、このクエリの対象外になってしまいます。

設定手順:

  1. コースの編集モードをオン
  2. 修了証アクティビティの編集 → 「完了条件」
  3. 「証明書を受け取る」にチェックを入れて保存

絞り込みたいときは

特定コースに絞る場合はWHERE句に追加します。

AND c.id = 対象コースID
-- または
AND c.shortname = 'コースの短縮名'

コーホートで絞る場合はJOINを追加します。

JOIN {cohort_members} cohm ON cohm.userid = u.id AND cohm.cohortid = 対象コーホートID

生成AIでSQLを書いてもらうTIPS

Moodle固有のテーブル構造を把握しながらSQLを書くのは、最初はなかなかハードルが高いです。ClaudeなどのAIを使うと効率よく書けます。実際、この記事のSQLもほぼClaudeと対話しながら作りました。

プロンプトのコツ

Moodle固有のルールを最初に伝える

Moodleのreport_customsqlプラグイン用のSQLを書いてください。
以下のルールがあります:
- テーブル名は{}で囲む(例:{user}、{course})
- LIMIT句は書かない
- MariaDB(MySQL互換)で動作すること

欲しい列を具体的に伝える

以下の列を持つレポートを作りたいです:
- ユーザー名・氏名
- コース名・登録日・経過日数
- アクティビティ名・種別・完了状態・完了日
- 修了証の発行状況

エラーが出たらそのまま貼る

エラーメッセージをそのままChatに貼ると原因と修正版SQLを返してくれます。「どのエラーメッセージをどう読めばいいか分からない」状態でも使えるのが便利なところです。

段階的に作る

一度にすべての列を含む複雑なSQLを作ろうとせず、まず動く最小構成を作ってから列を1つずつ追加していくと問題の切り分けがしやすくなります。

よくあるエラーと対処法

エラー 原因 対処
Table 'xxx.mdl_tablename' doesn't exist テーブル名をそのまま書いている {tablename} の形式に変更
near 'LIMIT 0, 2' クエリ内にLIMIT句を書いている LIMIT句を削除
Table doesn't exist プラグインが未インストール 対象プラグインのインストールを確認
アクティビティ名がNULLになる 対応テーブルのLEFT JOINが漏れている 該当アクティビティ種別のJOINを追加

まとめ

比較項目 標準レポート レポートビルダー(Workplace) Ad-hoc database queries
アクティビティ別完了 △(1コース内のみ)
複数コース横断
修了証発行状況
CSV出力
カスタマイズ性
SQL知識が必要 不要 不要 必要(AIで代替可)

「誰がどのアクティビティをどんな状態で完了しているか」を1つのレポートで確認したいなら、Ad-hoc database queriesが現時点では最も現実的な選択肢です。SQLはAIを使って効率よく書けるので、SQL経験が少ない方でも十分活用できると思います。

Moodle Workplaceを使う場合の補足

Ad-hoc database queriesはMoodle Workplaceでも利用できますが、以下の点に注意が必要です。

修了証のテーブルが異なる:Moodle Workplaceでは修了証に tool_certificate モジュールが使われており、テーブル名やJOINの書き方が標準Moodleと異なります。上記SQLをそのまま使うとエラーが出るので、環境に合わせた書き換えが必要です。

テーブルの存在確認方法

-- モジュール名の一覧確認
SELECT id, name FROM {modules} ORDER BY name

-- 特定テーブルの存在確認(エラーが出なければ存在する)
SELECT id FROM {tool_certificate_issues}

Workplaceのバージョンや構成によってテーブル名が異なる場合があるため、環境ごとに確認しながら進めるのがおすすめです。

参考リンク


※ この記事は Zenn (rublix) にも投稿しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?