added Mater VIEW 'conversion_funnel' in Pet Project

This commit is contained in:
Dmitry Medvedev
2026-06-24 15:50:06 +05:00
parent 6b22a048fc
commit 0fca2bcd7a
@@ -0,0 +1,152 @@
CREATE MATERIALIZED VIEW conversion_funnel AS
-- CTE какое кол-во человек записалось на курс
WITH
enrolled_users AS (
SELECT
course_id,
COUNT(*) AS enrolled
FROM pet_enrollments pe
GROUP BY course_id
),
-- СТЕ на начавших смотреть курс
started_users AS (
SELECT
pc.id AS course_id,
COUNT(DISTINCT plv.user_id) AS started
FROM pet_courses pc
LEFT JOIN pet_lessons pl
ON pc.id = pl.course_id
LEFT JOIN pet_lesson_views plv
ON plv.lesson_id = pl.id
GROUP BY pc.id
),
--СТЕ на кол-во просмотров курса и прогресс по курсу
user_progress AS (
SELECT
pc.id AS course_id,
plv.user_id,
COUNT(DISTINCT lesson_id) AS count_views,
count_lesson_in_course.count_lesson_in_course AS count_lesson_in_course,
COUNT(DISTINCT lesson_id) * 1.0 / count_lesson_in_course AS progress
FROM pet_courses pc
LEFT JOIN pet_lessons pl
ON pl.course_id = pc.id
LEFT JOIN pet_lesson_views plv
ON plv.lesson_id = pl.id
LEFT JOIN (
SELECT
pl.course_id,
COUNT(*) AS count_lesson_in_course
FROM pet_lessons pl
GROUP BY pl.course_id
) AS count_lesson_in_course
ON count_lesson_in_course.course_id = pc.id
GROUP BY pc.id, plv.user_id, count_lesson_in_course
),
main_table AS (
SELECT
pc.id AS course_id,
pc.title AS course_title,
'registered' AS stage_name,
0 AS stage_order,
(SELECT COUNT(*) FROM pet_users pu) AS users_count,
ROUND(100, 2) || '%' AS conversion_from_previous,
ROUND(100, 2) || '%' AS conversion_from_start
FROM pet_courses pc
UNION ALL
SELECT
pc.id AS course_id,
pc.title AS course_title,
'enrolled' AS stage_name,
1 AS stage_order,
enrolled_users.enrolled,
ROUND(enrolled_users.enrolled * 100.0 / (SELECT COUNT(*) FROM pet_users pu), 2) || '%' AS conversion_from_previous,
ROUND(enrolled_users.enrolled * 100.0 / (SELECT COUNT(*) FROM pet_users pu), 2) || '%' AS conversion_from_start
FROM pet_courses pc
LEFT JOIN enrolled_users
ON enrolled_users.course_id = pc.id
UNION ALL
SELECT
pc.id AS course_id,
pc.title AS course_title,
'started' AS stage_name,
2 AS stage_order,
started_users.started,
ROUND(started_users.started * 100.0 / enrolled_users.enrolled, 2) || '%' AS conversion_from_previous,
ROUND(started_users.started * 100.0 / (SELECT COUNT(*) FROM pet_users pu), 2) || '%' AS conversion_from_start
FROM pet_courses pc
LEFT JOIN started_users
ON started_users.course_id = pc.id
LEFT JOIN enrolled_users
ON enrolled_users.course_id = pc.id
UNION ALL
SELECT
pc.id AS course_id,
pc.title AS course_title,
'mid_progress' AS stage_name,
3 AS stage_order,
( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 0.5
),
ROUND(( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 0.5) * 100.0 / started_users.started, 2) || '%' AS conversion_from_previous,
ROUND(( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 0.5) * 100.0 / (SELECT COUNT(*) FROM pet_users pu), 2) || '%' AS conversion_from_start
FROM pet_courses pc
LEFT JOIN started_users
ON started_users.course_id = pc.id
UNION ALL
SELECT
pc.id AS course_id,
pc.title AS course_title,
'completed' AS stage_name,
4 AS stage_order,
( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 1),
ROUND(( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 1) * 100.0 /
( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 0.5), 2) || '%' AS conversion_from_previous,
ROUND(( SELECT COUNT(*) FROM user_progress
WHERE user_progress.course_id = pc.id AND user_progress.progress >= 1) * 100.0 /
(SELECT COUNT(*) FROM pet_users pu), 2) || '%' AS conversion_from_start
FROM pet_courses pc
ORDER BY course_id, stage_order
)
-- main select
SELECT
course_id,
course_title,
stage_name,
users_count,
conversion_from_previous,
conversion_from_start
FROM main_table;