Course designers, assessment teams and department chairs may want to see every quiz in every course in one list. This Brightspace quiz attempts report helps spot quizzes few learners finished or that score unusually low, using Brightspace Data Sets rather than opening each course to collect the results.

Where the data comes from: Brightspace Data Sets, the CSV extracts Brightspace publishes in Data Hub. This is not a built-in Brightspace report or screen. Rowseta syncs these data sets for you, or your administrator can download the extracts for your own SQL tool.

Run this query

Choose where to run it

  • In Rowseta: open Reports > New report and paste the query into the SQL editor on the Query tab. Sync the data sets listed below first.
  • In your own setup: load your Data Hub extracts into your own SQL tool, one table per data set, named without spaces (User Enrollments becomes UserEnrollments), after applying differentials to the fulls. Another SQL tool may need small changes to these queries.

A free Rowseta Desktop app is coming soon.

Load Quiz Objects, Quiz Attempts, User Enrollments, Role Details and Organizational Units.

Run the quiz report query

Edit the role names on line 5. The query removes duplicate source rows before counting, and matches attempts to learners enrolled in that same course.

sql
-- Edit the role names on the RoleName IN line to choose who counts as a learner.
WITH learner_roles AS (
    SELECT DISTINCT RoleId
    FROM RoleDetails
    WHERE RoleName IN ('Student')
), Courses AS (
    SELECT DISTINCT OrgUnitId, Name
    FROM OrganizationalUnits WHERE Type = 'Course Offering'
), Enrollments AS (
    SELECT DISTINCT UserId, OrgUnitId, RoleId FROM UserEnrollments
), Learners AS (
    SELECT DISTINCT E.UserId, E.OrgUnitId
    FROM Enrollments E
    JOIN learner_roles ON learner_roles.RoleId = E.RoleId
    JOIN Courses ON Courses.OrgUnitId = E.OrgUnitId
), CourseLearners AS (
    SELECT OrgUnitId, COUNT(*) AS Learners FROM Learners GROUP BY OrgUnitId
), Quizzes AS (
    SELECT DISTINCT QuizId, QuizName, OrgUnitId FROM QuizObjects
), Attempts AS (
    SELECT DISTINCT AttemptId, QuizId, UserId, OrgUnitId, TimeCompleted, Score, PossibleScore
    FROM QuizAttempts
    WHERE COALESCE(TRY_CAST(IsDeleted AS BOOLEAN), false) = false
      AND TimeCompleted IS NOT NULL
), Finished AS (
    SELECT A.* FROM Attempts A
    JOIN Learners ON Learners.UserId = A.UserId AND Learners.OrgUnitId = A.OrgUnitId
), Totals AS (
    SELECT QuizId, OrgUnitId, COUNT(DISTINCT UserId) AS LearnersFinished,
           COUNT(*) AS FinishedAttempts,
           ROUND(AVG(CASE WHEN PossibleScore > 0 THEN Score * 100.0 / PossibleScore END), 1) AS AverageScorePercent
    FROM Finished GROUP BY QuizId, OrgUnitId
)
SELECT Q.QuizId, Q.QuizName, Q.OrgUnitId, Courses.Name AS CourseName,
       COALESCE(CourseLearners.Learners, 0) AS Learners,
       COALESCE(Totals.LearnersFinished, 0) AS LearnersFinished,
       COALESCE(Totals.FinishedAttempts, 0) AS FinishedAttempts, Totals.AverageScorePercent
FROM Quizzes Q
JOIN Courses ON Courses.OrgUnitId = Q.OrgUnitId
LEFT JOIN CourseLearners ON CourseLearners.OrgUnitId = Q.OrgUnitId
LEFT JOIN Totals ON Totals.QuizId = Q.QuizId AND Totals.OrgUnitId = Q.OrgUnitId
ORDER BY Q.OrgUnitId, Q.QuizId;

The query counts people whose role is named Student in Role Details. To count other roles, edit the RoleName IN list near the top, for example ('Student', 'Learner'). Names must match exactly. Joins use RoleId, so two roles with the same name both count, and a renamed role follows its current name.

To narrow attempts to one term's dates, append AND CAST(TimeCompleted AS DATE) BETWEEN DATE '2025-09-01' AND DATE '2025-12-31' to line 24, the line containing AND TimeCompleted IS NOT NULL. Both days are included in UTC. This limits attempts, not the course enrollment count.

Read the results per quiz

Fictional sample data: all 6 rows.

QuizId QuizName OrgUnitId CourseName Learners LearnersFinished FinishedAttempts AverageScorePercent
11 Quiz 1 100 Same course 2 2 3 70
12 Quiz 1 100 Same course 2 1 1 30
13 No attempts 100 Same course 2 0 0 null
21 Quiz 1 200 Same course 3 2 2 73.3
22 Quiz 2 200 Same course 3 1 1 null
31 Quiz 1 300 Same course 1 1 1 20

Learners counts enrolled learners in the course; LearnersFinished counts those with a finished attempt. FinishedAttempts includes repeats, so one learner can add several attempts. Unfinished and deleted attempts are left out. The average uses finished attempts with a possible score above zero, not each learner's best score or the grade released to the gradebook. A null average means none had a usable score.

Quizzes without attempts still appear. The two Quiz 1 rows in course 100 stay separate because the query groups by QuizId. The same quiz and course names elsewhere also stay separate through their IDs. Use those IDs when following up on an unusually low average.

When it goes wrong

What you seeWhat to do
No learners appearOne possible cause is that no role in Role Details matches the role names list. Check the exact role names in Role Details and edit the list at the top of the query. A Rowseta session limited to one course cannot read Role Details, so sign in directly.
A quiz is missingCheck that Quiz Objects and its Course Offering are loaded.
An average is blankNo finished attempt has both a score and a possible score greater than zero.

Next guides

Failing students across courses with Brightspace Data Sets: final grades below a pass markHow to join Brightspace Data Sets: keys and a worked query