156 lines
4.7 KiB
SQL
156 lines
4.7 KiB
SQL
CREATE MATERIALIZED
|
|
VIEW conversion_funnel AS
|
|
|
|
-- CTE какое кол-во человек записалось на курс
|
|
WITH
|
|
|
|
enrolled_users
|
|
AS
|
|
(
|
|
SELECT
|
|
course_id,
|
|
user_id,
|
|
COUNT(*) OVER (PARTITION BY course_id) AS enrolled_count
|
|
FROM pet_enrollments pe
|
|
),
|
|
|
|
-- СТЕ на начавших смотреть курс
|
|
started_users
|
|
AS
|
|
(
|
|
SELECT
|
|
eu.course_id,
|
|
COUNT(DISTINCT plv.user_id) AS started
|
|
FROM enrolled_users eu -- Базой берем записанных пользователей
|
|
LEFT JOIN pet_lessons pl
|
|
ON eu.course_id = pl.course_id
|
|
LEFT JOIN pet_lesson_views plv
|
|
ON plv.lesson_id = pl.id AND plv.user_id = eu.user_id
|
|
-- Проверяем, что смотрел именно записанный юзер
|
|
GROUP BY eu.course_id
|
|
),
|
|
|
|
|
|
--СТЕ на кол-во просмотров курса и прогресс по курсу
|
|
user_progress
|
|
AS
|
|
(
|
|
SELECT
|
|
eu.course_id,
|
|
eu.user_id,
|
|
COUNT(DISTINCT plv.lesson_id) * 1.0 / count_lesson_in_course.count_lesson_in_course AS progress
|
|
FROM enrolled_users eu -- Базой берем записанных пользователей
|
|
LEFT JOIN pet_lessons pl
|
|
ON pl.course_id = eu.course_id
|
|
LEFT JOIN pet_lesson_views plv
|
|
ON plv.lesson_id = pl.id AND plv.user_id = eu.user_id -- Просмотры могут быть NULL, если записался, но не смотрел
|
|
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 = eu.course_id
|
|
GROUP BY eu.course_id, eu.user_id, count_lesson_in_course.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,
|
|
COALESCE(eu.enrolled_count, 0),
|
|
ROUND(COALESCE(eu.enrolled_count, 0) * 100.0 / NULLIF((SELECT COUNT(*) FROM pet_users), 0), 2) || '%' AS conversion_from_previous,
|
|
ROUND(COALESCE(eu.enrolled_count, 0) * 100.0 / NULLIF((SELECT COUNT(*) FROM pet_users), 0), 2) || '%' AS conversion_from_start
|
|
FROM pet_courses pc
|
|
LEFT JOIN (SELECT course_id, MAX(enrolled_count) AS enrolled_count
|
|
FROM enrolled_users
|
|
GROUP BY course_id) eu
|
|
ON eu.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,
|
|
COALESCE(su.started, 0),
|
|
ROUND(COALESCE(su.started, 0) * 100.0 / NULLIF(eu.enrolled_count, 0), 2) || '%' AS conversion_from_previous,
|
|
ROUND(COALESCE(su.started, 0) * 100.0 / NULLIF((SELECT COUNT(*) FROM pet_users), 0), 2) || '%' AS conversion_from_start
|
|
FROM pet_courses pc
|
|
LEFT JOIN (SELECT course_id, MAX(enrolled_count) AS enrolled_count
|
|
FROM enrolled_users
|
|
GROUP BY course_id) eu
|
|
ON eu.course_id = pc.id
|
|
LEFT JOIN started_users su
|
|
ON su.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 up
|
|
WHERE up.course_id = pc.id AND up.progress >= 0.5),
|
|
ROUND((SELECT COUNT(*)
|
|
FROM user_progress up
|
|
WHERE up.course_id = pc.id AND up.progress >= 0.5) * 100.0 / NULLIF(su.started, 0), 2) || '%' AS conversion_from_previous,
|
|
ROUND((SELECT COUNT(*)
|
|
FROM user_progress up
|
|
WHERE up.course_id = pc.id AND up.progress >= 0.5) * 100.0 / NULLIF((SELECT COUNT(*) FROM pet_users), 0), 2) || '%' AS conversion_from_start
|
|
FROM pet_courses pc
|
|
LEFT JOIN started_users su
|
|
ON su.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 up
|
|
WHERE up.course_id = pc.id AND up.progress >= 1),
|
|
ROUND((SELECT COUNT(*)
|
|
FROM user_progress up
|
|
WHERE up.course_id = pc.id AND up.progress >= 1) * 100.0 / NULLIF((SELECT COUNT(*) FROM user_progress up WHERE up.course_id = pc.id AND up.progress >= 0.5), 0), 2) || '%' AS conversion_from_previous,
|
|
ROUND((SELECT COUNT(*)
|
|
FROM user_progress up
|
|
WHERE up.course_id = pc.id AND up.progress >= 1) * 100.0 / NULLIF((SELECT COUNT(*) FROM pet_users), 0), 2) || '%' AS conversion_from_start
|
|
FROM pet_courses pc
|
|
)
|
|
-- main select
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
stage_name,
|
|
users_count,
|
|
conversion_from_previous,
|
|
conversion_from_start
|
|
|
|
FROM main_table
|
|
ORDER BY course_id, stage_order; |