BEGIN; CREATE MATERIALIZED VIEW course_summary AS WITH courses_users AS ( SELECT c.id AS course_id, c.title AS course_name, COUNT(DISTINCT user_id) AS unique_users FROM courses c LEFT join enrollments e ON c.id = e.course_id GROUP BY c.id, c.title ), courses_views AS ( SELECT l.course_id, COUNT(DISTINCT l.id) AS lessons_count, COUNT(lv.id) AS total_views, MAX(lv.viewed_at) AS last_viewed_at, MIN(lv.viewed_at) AS first_viewed_at FROM lessons l JOIN lesson_views lv ON l.id = lv.lesson_id GROUP BY l.course_id ) SELECT cu.course_id, cu.course_name, cu.unique_users, cv.lessons_count, cv.total_views, ROUND(cv.total_views::DECIMAL / NULLIF(cu.unique_users, 0), 2) AS avg_views_per_user, cv.first_viewed_at, cv.last_viewed_at FROM courses_users cu LEFT JOIN courses_views cv USING(course_id) ORDER BY cu.course_id; COMMIT;