Searching for failing students across courses? This query lists available final grades below a common pass mark. It can support an early alert list or a review of at-risk students, but a low grade alone does not establish risk or explain why. Check each row before arranging follow-up.

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.

This query needs User Enrollments, Role Details, Grade Results, Grade Objects, Users and Organizational Units. The reference links explain the columns and keys in each data set.

Run the below-pass-mark final grades query

Use the complete query below. It uses a passing mark of 50 percent. To use another percentage, change 50 on line 4, the line containing SELECT 50 AS PassMark, then run the query. The same threshold applies across every course in this query, so use it only when that comparison suits your review.

A role counts as a learner role when Role Details has ShowInGrades true and DeletedBy empty. Each RoleId is judged on its own and role names are never read. Preview and testing roles that show in grades pass this rule too, so to use your own roles, replace the body of learner_roles with your role IDs: SELECT UNNEST([103, 121]) AS RoleId. A valid adjusted final grade takes priority over a calculated final grade; individual assessments are excluded. Possible points must be greater than zero to produce a percentage.

sql
-- Change 50 below to use a different passing percentage.
-- Adjusted final grades take priority over calculated final grades when valid.
WITH Settings AS (
    SELECT 50 AS PassMark
), learner_roles AS (
    SELECT DISTINCT RoleId
    FROM RoleDetails
    WHERE RoleId IS NOT NULL
      AND NULLIF(trim(CAST(DeletedBy AS VARCHAR)), '') IS NULL
      AND COALESCE(lower(trim(CAST(ShowInGrades AS VARCHAR))) IN ('true', '1'), false)
), Learners AS (
    SELECT DISTINCT UserEnrollments.OrgUnitId, UserEnrollments.UserId
    FROM UserEnrollments
    JOIN learner_roles ON learner_roles.RoleId = UserEnrollments.RoleId
), Candidates AS (
    SELECT GradeResults.OrgUnitId, GradeResults.UserId, GradeResults.GradeObjectId,
           GradeResults.PointsNumerator, GradeResults.PointsDenominator,
           ROW_NUMBER() OVER (
               PARTITION BY GradeResults.OrgUnitId, GradeResults.UserId
               ORDER BY GradeObjects.GradeObjectTypeId DESC, GradeObjects.GradeObjectId
           ) AS FinalRank
    FROM GradeResults
    JOIN GradeObjects ON GradeObjects.GradeObjectId = GradeResults.GradeObjectId
                     AND GradeObjects.OrgUnitId = GradeResults.OrgUnitId
    WHERE GradeObjects.GradeObjectTypeId IN (7, 8)
      AND COALESCE(TRY_CAST(GradeObjects.IsDeleted AS BOOLEAN), false) = false
      AND COALESCE(TRY_CAST(GradeResults.IsDeleted AS BOOLEAN), false) = false
      AND GradeResults.PointsDenominator IS NOT NULL AND GradeResults.PointsDenominator > 0
)
SELECT Courses.OrgUnitId AS CourseId, Courses.Name AS CourseName,
       Users.UserId, Users.FirstName, Users.LastName, Candidates.GradeObjectId,
       Candidates.PointsNumerator * 100.0 / Candidates.PointsDenominator AS GradePercent
FROM Candidates
JOIN Learners ON Learners.OrgUnitId = Candidates.OrgUnitId AND Learners.UserId = Candidates.UserId
JOIN Users ON Users.UserId = Candidates.UserId
JOIN OrganizationalUnits AS Courses ON Courses.OrgUnitId = Candidates.OrgUnitId
CROSS JOIN Settings
WHERE Courses.Type = 'Course Offering'
  AND COALESCE(TRY_CAST(Courses.IsDeleted AS BOOLEAN), false) = false
  AND Users.DateDeleted IS NULL AND Candidates.FinalRank = 1
  AND Candidates.PointsNumerator * 100.0 / Candidates.PointsDenominator < Settings.PassMark
ORDER BY CourseId, Users.UserId, Candidates.GradeObjectId;

The percentage is earned points multiplied by 100 and divided by possible points. Exactly 50 is not below a pass mark of 50. For matching final grade types, the lowest grade object ID wins per learner and course.

Missing grades do not become failures: learners without a selected percentage are absent. Review missing final grades separately. This query does not apply course-specific passing rules or release status. Use it for follow-up with the common threshold you chose.

Review final grades below the pass mark

Fictional sample data: the first eight rows. Your own data will give different names, IDs and values.

CourseId CourseName UserId FirstName LastName GradeObjectId GradePercent
100 Fictional course, revised 910 Fictional Person 910 40200 40.0
100 Fictional course, revised 911 Fictional Person 911 40200 40.0
100 Fictional course, revised 1000 Fictional Same person 40200 40.0
100 Fictional course, revised 1002 Fictional Person 1002 40200 30.0
100 Fictional course, revised 1003 Fictional Person 1003 40200 30.0
100 Fictional course, revised 1005 Fictional Person 1005 40200 49.5
100 Fictional course, revised 1006 Fictional Person 1006 40200 40.0
100 Fictional course, revised 1008 Fictional Same person 40200 30.0

The rows show the selected GradeObjectId and GradePercent for each course and learner; 49.5 is below the sample threshold of 50. Use the course and user IDs to distinguish similar names, and review the selected final grade before acting on a row.

When it goes wrong

What you seeWhat to do
A learner with no final grade is absentMissing final grades are not converted to zero. Review missing grades separately.
A grade at the passing mark is absentThe comparison is strictly below the mark. A grade equal to the threshold is not included.
The selected grade differs from a calculated gradeA valid adjusted final grade takes priority. Compare the selected GradeObjectId with Grade Objects and Grade Results.
No learners appearOne possible cause is that no role passed the learner rule. Check ShowInGrades and DeletedBy in Role Details, or use your own role IDs. A Rowseta session limited to one course cannot read Role Details, so sign in directly.

Next guides

At-risk students in Brightspace: who has not opened a course in 5 daysHow to join Brightspace Data Sets: keys and a worked query