From 18f736dea4527cdb67822b07750c3fda30fab324 Mon Sep 17 00:00:00 2001 From: SERGEY_KONEV Date: Wed, 17 Dec 2025 14:28:42 +0300 Subject: [PATCH 1/2] added three data_mart_files --- skonev/postgresql/dm_course_summary.sql | 39 +++++++++++++++++++ skonev/postgresql/dm_platform_summary.sql | 20 ++++++++++ .../postgresql/dm_user_activity_summary.sql | 38 ++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 skonev/postgresql/dm_course_summary.sql create mode 100644 skonev/postgresql/dm_platform_summary.sql create mode 100644 skonev/postgresql/dm_user_activity_summary.sql diff --git a/skonev/postgresql/dm_course_summary.sql b/skonev/postgresql/dm_course_summary.sql new file mode 100644 index 0000000..ea9e711 --- /dev/null +++ b/skonev/postgresql/dm_course_summary.sql @@ -0,0 +1,39 @@ +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; + + diff --git a/skonev/postgresql/dm_platform_summary.sql b/skonev/postgresql/dm_platform_summary.sql new file mode 100644 index 0000000..ddf3416 --- /dev/null +++ b/skonev/postgresql/dm_platform_summary.sql @@ -0,0 +1,20 @@ +BEGIN; + +CREATE MATERIALIZED VIEW platform_summary AS +SELECT + (SELECT COUNT(*) FROM users) AS total_users, + (SELECT COUNT(*) FROM courses) AS total_courses, + (SELECT COUNT(*) FROM lessons) AS total_lessons, + (SELECT COUNT(DISTINCT user_id) FROM lesson_views) AS users_with_views, + ROUND( + (SELECT COUNT(*)::DECIMAL FROM lessons) / + NULLIF((SELECT COUNT(DISTINCT course_id) FROM lessons), 0), + 2 + ) AS avg_lessons_per_course, + ROUND( + (SELECT COUNT(*)::DECIMAL FROM lesson_views) / + NULLIF((SELECT COUNT(DISTINCT lesson_id) FROM lesson_views), 0), + 2 + ) AS avg_views_per_lesson; + +COMMIT; \ No newline at end of file diff --git a/skonev/postgresql/dm_user_activity_summary.sql b/skonev/postgresql/dm_user_activity_summary.sql new file mode 100644 index 0000000..af431bc --- /dev/null +++ b/skonev/postgresql/dm_user_activity_summary.sql @@ -0,0 +1,38 @@ +BEGIN; + +CREATE MATERIALIZED VIEW user_activity_summary AS +WITH users_views AS ( +SELECT + u.id AS user_id, + u.name, + COUNT(DISTINCT lv.lesson_id) AS viewed_lessons_COUNT, + MAX(lv.viewed_at) AS last_view, + MIN(lv.viewed_at) AS first_view +FROM users AS u +JOIN lesson_views AS lv on u.id = lv.user_id +GROUP BY u.id + +), +users_engagement AS ( +SELECT + e.user_id AS user_id, + COUNT(l.id) AS lessons_cnt, + COUNT(DISTINCT course_id) AS enrollment_count +FROM enrollments AS e +JOIN lessons AS l using(course_id) +GROUP BY e.user_id +) + +SELECT + uv.user_id, + uv.name, + ue.enrollment_count, + uv.viewed_lessons_count, + uv.lASt_view, + uv.first_view, + ROUND(uv.viewed_lessons_count::DECIMAL / NULLIF(ue.lessons_cnt, 0) * 100, 2) AS engagement_rate +FROM users_views AS uv +LEFT JOIN users_engagement AS ue using (user_id) +ORDER BY uv.user_id + +COMMIT; \ No newline at end of file From d7a1b1921308d06ef76e5e77b06243a87ee169ce Mon Sep 17 00:00:00 2001 From: SERGEY_KONEV Date: Fri, 19 Dec 2025 11:39:12 +0300 Subject: [PATCH 2/2] fix course_summary and user_activity files --- skonev/postgresql/dm_course_summary.sql | 12 ++++++++++-- skonev/postgresql/dm_user_activity_summary.sql | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/skonev/postgresql/dm_course_summary.sql b/skonev/postgresql/dm_course_summary.sql index ea9e711..30ff521 100644 --- a/skonev/postgresql/dm_course_summary.sql +++ b/skonev/postgresql/dm_course_summary.sql @@ -13,25 +13,33 @@ 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 +), +courses_lessons AS ( + SELECT + course_id, + COUNT(DISTINCT id) AS lessons_count + FROM lessons + GROUP BY course_id ) + SELECT cu.course_id, cu.course_name, cu.unique_users, - cv.lessons_count, + cl.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) +LEFT JOIN courses_lessons cl USING(course_id) ORDER BY cu.course_id; COMMIT; diff --git a/skonev/postgresql/dm_user_activity_summary.sql b/skonev/postgresql/dm_user_activity_summary.sql index af431bc..048c8b3 100644 --- a/skonev/postgresql/dm_user_activity_summary.sql +++ b/skonev/postgresql/dm_user_activity_summary.sql @@ -5,7 +5,7 @@ WITH users_views AS ( SELECT u.id AS user_id, u.name, - COUNT(DISTINCT lv.lesson_id) AS viewed_lessons_COUNT, + COUNT(DISTINCT lv.lesson_id) AS viewed_lessons_count, MAX(lv.viewed_at) AS last_view, MIN(lv.viewed_at) AS first_view FROM users AS u @@ -16,7 +16,7 @@ GROUP BY u.id users_engagement AS ( SELECT e.user_id AS user_id, - COUNT(l.id) AS lessons_cnt, + COUNT(DISTINCT l.id) AS lessons_cnt, COUNT(DISTINCT course_id) AS enrollment_count FROM enrollments AS e JOIN lessons AS l using(course_id) @@ -28,7 +28,7 @@ SELECT uv.name, ue.enrollment_count, uv.viewed_lessons_count, - uv.lASt_view, + uv.last_view, uv.first_view, ROUND(uv.viewed_lessons_count::DECIMAL / NULLIF(ue.lessons_cnt, 0) * 100, 2) AS engagement_rate FROM users_views AS uv