| | 436 | |
| | 437 | |
| | 438 | == 6# Monthly analysis of course activity, completions, instructor involvement, and student success within a given year |
| | 439 | |
| | 440 | This SQL query provides a month-by-month analysis of the platform within a selected year, combining course activity data with student performance indicators. |
| | 441 | The report evaluates what happens in each month through: |
| | 442 | - The total number of course enrollments. |
| | 443 | - The total number of completed courses |
| | 444 | - The number of instructors whose courses had enrollments |
| | 445 | - The average student score achieved through quiz attempts in active courses |
| | 446 | - The average success at the course level |
| | 447 | - The final average success at the month level across all active courses |
| | 448 | |
| | 449 | This query: |
| | 450 | - Groups platform activity month by month within a given year |
| | 451 | - Combines enrollment, completion, instructor, and quiz performance data |
| | 452 | - Calculates student success using average quiz score |
| | 453 | - Derives course-level average success and final monthly average success |
| | 454 | - Provides a broader analytical picture of platform activity and learning outcomes over time |
| | 455 | |
| | 456 | {{{ |
| | 457 | WITH student_course_month_performance AS ( |
| | 458 | SELECT |
| | 459 | EXTRACT(YEAR FROM qa.attempt_date) AS year, |
| | 460 | EXTRACT(MONTH FROM qa.attempt_date) AS month, |
| | 461 | c.course_id, |
| | 462 | qa.user_id, |
| | 463 | ROUND(AVG(qa.score), 2) AS avg_student_score |
| | 464 | FROM quiz_attempt qa |
| | 465 | JOIN quiz q |
| | 466 | ON q.quiz_id = qa.quiz_id |
| | 467 | JOIN lesson l |
| | 468 | ON l.lesson_id = q.lesson_id |
| | 469 | JOIN module m |
| | 470 | ON m.module_id = l.module_id |
| | 471 | JOIN course c |
| | 472 | ON c.course_id = m.course_id |
| | 473 | GROUP BY |
| | 474 | EXTRACT(YEAR FROM qa.attempt_date), |
| | 475 | EXTRACT(MONTH FROM qa.attempt_date), |
| | 476 | c.course_id, |
| | 477 | qa.user_id |
| | 478 | ), |
| | 479 | course_month_performance AS ( |
| | 480 | SELECT |
| | 481 | year, |
| | 482 | month, |
| | 483 | course_id, |
| | 484 | ROUND(AVG(avg_student_score), 2) AS avg_course_success |
| | 485 | FROM student_course_month_performance |
| | 486 | GROUP BY |
| | 487 | year, |
| | 488 | month, |
| | 489 | course_id |
| | 490 | ), |
| | 491 | month_performance_summary AS ( |
| | 492 | SELECT |
| | 493 | year, |
| | 494 | month, |
| | 495 | ROUND(AVG(avg_course_success), 2) AS final_month_success |
| | 496 | FROM course_month_performance |
| | 497 | GROUP BY |
| | 498 | year, |
| | 499 | month |
| | 500 | ) |
| | 501 | SELECT |
| | 502 | EXTRACT(YEAR FROM e.enroll_date) AS year, |
| | 503 | EXTRACT(MONTH FROM e.enroll_date) AS month, |
| | 504 | COUNT(DISTINCT e.enrollment_id) AS total_enrollments, |
| | 505 | COUNT(DISTINCT CASE |
| | 506 | WHEN e.completion_status = 'COMPLETED' THEN e.enrollment_id |
| | 507 | END) AS completed_enrollments, |
| | 508 | COUNT(DISTINCT c.instructor_id) AS active_instructors, |
| | 509 | ROUND(AVG(scmp.avg_student_score), 2) AS avg_student_success, |
| | 510 | ROUND(AVG(cmp.avg_course_success), 2) AS avg_course_success, |
| | 511 | mps.final_month_success |
| | 512 | FROM enrollment e |
| | 513 | JOIN course c |
| | 514 | ON c.course_id = e.course_id |
| | 515 | LEFT JOIN student_course_month_performance scmp |
| | 516 | ON scmp.year = EXTRACT(YEAR FROM e.enroll_date) |
| | 517 | AND scmp.month = EXTRACT(MONTH FROM e.enroll_date) |
| | 518 | AND scmp.course_id = e.course_id |
| | 519 | AND scmp.user_id = e.user_id |
| | 520 | LEFT JOIN course_month_performance cmp |
| | 521 | ON cmp.year = EXTRACT(YEAR FROM e.enroll_date) |
| | 522 | AND cmp.month = EXTRACT(MONTH FROM e.enroll_date) |
| | 523 | AND cmp.course_id = e.course_id |
| | 524 | LEFT JOIN month_performance_summary mps |
| | 525 | ON mps.year = EXTRACT(YEAR FROM e.enroll_date) |
| | 526 | AND mps.month = EXTRACT(MONTH FROM e.enroll_date) |
| | 527 | GROUP BY |
| | 528 | EXTRACT(YEAR FROM e.enroll_date), |
| | 529 | EXTRACT(MONTH FROM e.enroll_date), |
| | 530 | mps.final_month_success |
| | 531 | ORDER BY |
| | 532 | year, |
| | 533 | month; |
| | 534 | |
| | 535 | }}} |
| | 536 | |
| | 537 | |
| | 538 | ==== Solution Relational Algebra |
| | 539 | |
| | 540 | - E(enrollment_id, user_id, course_id, enroll_date, completion_status, progress_percentage) |
| | 541 | - C(course_id, name, price, status, instructor_id) |
| | 542 | - Q(quiz_id, total_points, passing_score, lesson_id) |
| | 543 | - QA(attempt_id, score, attempt_date, user_id, quiz_id) |
| | 544 | - L(lesson_id, module_id, title, material) |
| | 545 | - M(module_id, course_id, title, description) |
| | 546 | |
| | 547 | |
| | 548 | **JOIN on all tables:** |
| | 549 | |
| | 550 | J1 ← QA ⋈ QA.quiz_id = Q.quiz_id Q |
| | 551 | |
| | 552 | J2 ← J1 ⋈ Q.lesson_id = L.lesson_id L |
| | 553 | |
| | 554 | J3 ← J2 ⋈ L.module_id = M.module_id M |
| | 555 | |
| | 556 | J4 ← J3 ⋈ M.course_id = C.course_id C |
| | 557 | |
| | 558 | J5 ← E ⋈ E.course_id = C.course_id C |
| | 559 | |
| | 560 | **Projection with date transformation for student-course-month performance** |
| | 561 | |
| | 562 | F1 ← π QA.user_id, C.course_id, QA.score, YEAR(QA.attempt_date) → Year, MONTH(QA.attempt_date) → Month (J4) |
| | 563 | |
| | 564 | **Grouping and aggregate calculations at student-course-month level** |
| | 565 | |
| | 566 | G1 ← Year, Month, course_id, user_id γ |
| | 567 | AVG(score) → Avg_Student_Score (F1) |
| | 568 | |
| | 569 | **Grouping and aggregate calculations at course-month level** |
| | 570 | |
| | 571 | G2 ← Year, Month, course_id γ |
| | 572 | AVG(Avg_Student_Score) → Avg_Course_Success (G1) |
| | 573 | |
| | 574 | **Grouping and aggregate calculations at the month level** |
| | 575 | G3 ← Year, Month γ |
| | 576 | AVG(Avg_Course_Success) → Final_Month_Success (G2) |
| | 577 | |
| | 578 | **Projection with date transformation for enrollment activity** |
| | 579 | F2 ← π enrollment_id, user_id, course_id, instructor_id, completion_status, YEAR(enroll_date) → Year, MONTH(enroll_date) → Month (J5) |
| | 580 | |
| | 581 | **Grouping and aggregate calculations for monthly platform activity** |
| | 582 | G4 ← Year, Month γ |
| | 583 | COUNT(DISTINCT enrollment_id) → Total_Enrollments, |
| | 584 | COUNT(DISTINCT [completion_status = 'COMPLETED'] enrollment_id) → Completed_Enrollments, |
| | 585 | COUNT(DISTINCT instructor_id) → Active_Instructors (F2) |
| | 586 | |
| | 587 | **Joining activity data with performance data** |
| | 588 | R1 ← G4 ⋈ G4.Year = G3.Year ∧ G4.Month = G3.Month G3 |
| | 589 | |
| | 590 | |
| | 591 | **Final projection** |
| | 592 | |
| | 593 | P ← π Year, Month, Total_Enrollments, Completed_Enrollments, Active_Instructors, Final_Month_Success (R1) |
| | 594 | |
| | 595 | |
| | 596 | **Chronological ordering by year** |
| | 597 | |
| | 598 | R_final ← τ Year, Month (P) |