Data AnalyticsDomain analytics and business cases

Education cohort analytics: attendance, completion and missing records

PK
Pankit Kumar
Sr. Data Scientist at Parexel (a Goldman Sachs–backed company) · 20 September 2026 · 3 min read
Technically reviewed by Ishaan Sharma
In this article (5 sections)

An attendance rate needs a population of sessions each learner was eligible to attend. Counting only recorded attendance rows can hide missing records; counting every scheduled session can penalize learners for canceled classes or sessions before enrollment.

Completion requires a separate cohort and outcome horizon. A learner can attend frequently without completing an assessment, and a missing assessment record is not automatically a failure.

Build the expected learner-session grid

The original synthetic learners, sessions and attendance records do not describe actual NeuraPath students.

Three sessions were held and a fourth was canceled. L3 enrolled after the first session. L4 withdrew after the second. For attendance, include held sessions on or after enrollment and strictly before withdrawal, where applicable.

sql
SELECT l.learner_id,s.session_id,COALESCE(a.status,'unknown') AS attendance_status
FROM learners l CROSS JOIN class_sessions s
LEFT JOIN attendance a
 ON a.learner_id=l.learner_id AND a.session_id=s.session_id
WHERE s.status='held' AND s.session_date<'2026-02-01'
 AND s.session_date>=l.enrolled_at
 AND (l.withdrawn_at IS NULL OR s.session_date<l.withdrawn_at)
ORDER BY l.learner_id,s.session_id;

The grid contains ten eligible learner-session pairs: three each for L1 and L2, two for L3 and two for L4. Seven are present, two absent and one unknown. L3's missing third-session record becomes visible because the expected grid exists independently of the attendance table.

Verify attendance and coverage separately

python
from build_and_verify import database

db = database()
expected = []
for learner,enrolled,withdrawn,due,assessment in db.execute('SELECT * FROM learners'):
    for session,day,status in db.execute("SELECT * FROM class_sessions WHERE status='held' AND session_date<'2026-02-01'"):
        if day>=enrolled and (withdrawn is None or day<withdrawn):
            row = db.execute('SELECT status FROM attendance WHERE learner_id=? AND session_id=?',(learner,session)).fetchone()
            expected.append((learner,session,row[0] if row else 'unknown'))
mature = db.execute("SELECT learner_id,assessment_status FROM learners WHERE assessment_due<'2026-02-01'").fetchall()
db.close()
present = sum(r[2]=='present' for r in expected)
absent = sum(r[2]=='absent' for r in expected)
unknown = sum(r[2]=='unknown' for r in expected)
assert (len(expected),present,absent,unknown)==(10,7,2,1)
assert {r[0] for r in mature}=={'L1','L2','L4'}
assert sum(status=='passed' for learner,status in mature)==1
print({'attendance_among_recorded':present/(present+absent),
       'coverage':(present+absent)/len(expected),
       'all_eligible_attendance_bounds':(present/10,(present+unknown)/10),
       'confirmed_completions':1,'mature_enrollment_population':len(mature)})

Recorded attendance is 7/9 ≈ 77.8% with 90% record coverage. Across all ten eligible pairs, attendance lies between 70% and 80% depending on the unresolved record. That range describes missing-data uncertainty, not a confidence interval.

Keep completion's denominator independent

By the cutoff, L1, L2 and L4 have reached their assessment deadline. L1 has a recorded pass, L2 has no recorded assessment outcome, and L4 withdrew. L3's later deadline has not arrived and is not yet mature for this completion view.

The confirmed completion share is one of three mature original enrollments. Do not remove L4 merely because withdrawal makes the rate less favorable. Conversely, do not describe L2 as an assessment failure when the outcome is missing.

Publish the status breakdown: confirmed completed, withdrawn, outcome unrecorded and not yet mature. If the program permits extensions or re-entry, define their effect on the cohort and cutoff before comparing batches.

Use the analysis to improve support

Attendance gaps can identify a need to verify records or offer appropriate support. They do not prove motivation, ability or future employment outcomes. The synthetic dataset contains no basis for those claims.

At the operational level, investigate whether attendance collection failed for a session, whether timetable changes were recorded, and whether enrollment dates align with actual access. A missing entire class register should not become a sudden drop in learner engagement.

For public reporting, define completion criteria and disclose the observation window. Comparing an ongoing cohort with a fully finished cohort can create an artificial performance gap.

Exercise: remove every attendance row for S2. Verify that the expected grid remains unchanged and the missing-record count increases. Then explain why an inner join would conceal the collection failure.

NeuraPath's Data Analytics with Generative AI course connects SQL population design with education reporting. A credible cohort dashboard separates participation, evidence coverage and verified completion.

Continue learning

This article is part of the Domain analytics and business cases sequence. Use the neighbouring tasks when you need the prerequisite or the next application.

PK
Pankit Kumar
Lead Instructor, NeuraPath Academy

Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.

This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.

Explore Data Analytics with Generative AI
Counselling is free · no obligation

Not sure which programme fits?

Tell us your background and we will map it to the right entry point — including saying so when a cheaper programme is the better fit. A counsellor replies within one working day.