105 lines
2.9 KiB
SQL
105 lines
2.9 KiB
SQL
DROP MATERIALIZED VIEW IF EXISTS dmezentsev.conversion_funnel;
|
|
CREATE MATERIALIZED VIEW dmezentsev.conversion_funnel AS
|
|
WITH progress AS (
|
|
-- Прогресс каждого пользователя по каждому курсу
|
|
SELECT
|
|
e.course_id,
|
|
e.user_id,
|
|
COUNT(DISTINCT l.id) AS total_lessons,
|
|
COUNT(DISTINCT lv.lesson_id) AS viewed_lessons,
|
|
ROUND(COUNT(DISTINCT lv.lesson_id) * 100.0 / NULLIF(COUNT(DISTINCT l.id), 0), 2) AS viewed_pct
|
|
FROM dmezentsev.enrollments e
|
|
LEFT JOIN dmezentsev.lessons l ON e.course_id = l.course_id
|
|
LEFT JOIN dmezentsev.lesson_views lv ON l.id = lv.lesson_id AND e.user_id = lv.user_id
|
|
GROUP BY e.course_id, e.user_id
|
|
),
|
|
|
|
funnel_stats AS (
|
|
-- Статистика по каждому курсу для всех этапов воронки
|
|
SELECT
|
|
c.id AS course_id,
|
|
c.title AS course_title,
|
|
(SELECT COUNT(*) FROM dmezentsev.users_) AS registered_count,
|
|
COUNT(DISTINCT e.user_id) AS enrolled_count,
|
|
COUNT(DISTINCT CASE WHEN p.viewed_lessons > 0 THEN e.user_id END) AS started_count,
|
|
COUNT(DISTINCT CASE WHEN p.viewed_pct >= 50 THEN e.user_id END) AS mid_progress_count,
|
|
COUNT(DISTINCT CASE WHEN p.viewed_pct = 100 THEN e.user_id END) AS completed_count
|
|
FROM dmezentsev.courses c
|
|
LEFT JOIN dmezentsev.enrollments e ON c.id = e.course_id
|
|
LEFT JOIN progress p ON e.course_id = p.course_id AND e.user_id = p.user_id
|
|
GROUP BY c.id, c.title
|
|
)
|
|
|
|
-- Соединяем этапы с помощью UNION ALL
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
stage_name,
|
|
users_count,
|
|
conversion_from_previous,
|
|
conversion_from_start
|
|
FROM (
|
|
-- Этап 1: registered
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
'registered' AS stage_name,
|
|
registered_count AS users_count,
|
|
0 AS conversion_from_previous,
|
|
100.00 AS conversion_from_start,
|
|
1 AS stage_order
|
|
FROM funnel_stats
|
|
|
|
UNION ALL
|
|
|
|
-- Этап 2: enrolled
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
'enrolled',
|
|
enrolled_count,
|
|
ROUND(100.0 * enrolled_count / NULLIF(registered_count, 0), 2),
|
|
ROUND(100.0 * enrolled_count / NULLIF(registered_count, 0), 2),
|
|
2 AS stage_order
|
|
FROM funnel_stats
|
|
|
|
UNION ALL
|
|
|
|
-- Этап 3: started
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
'started',
|
|
started_count,
|
|
ROUND(100.0 * started_count / NULLIF(enrolled_count, 0), 2),
|
|
ROUND(100.0 * started_count / NULLIF(registered_count, 0), 2),
|
|
3 AS stage_order
|
|
FROM funnel_stats
|
|
|
|
UNION ALL
|
|
|
|
-- Этап 4: mid_progress
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
'mid_progress',
|
|
mid_progress_count,
|
|
ROUND(100.0 * mid_progress_count / NULLIF(started_count, 0), 2),
|
|
ROUND(100.0 * mid_progress_count / NULLIF(registered_count, 0), 2),
|
|
4 AS stage_order
|
|
FROM funnel_stats
|
|
|
|
UNION ALL
|
|
|
|
-- Этап 5: completed
|
|
SELECT
|
|
course_id,
|
|
course_title,
|
|
'completed',
|
|
completed_count,
|
|
ROUND(100.0 * completed_count / NULLIF(mid_progress_count, 0), 2),
|
|
ROUND(100.0 * completed_count / NULLIF(registered_count, 0), 2),
|
|
5 AS stage_order
|
|
FROM funnel_stats
|
|
) AS funnel_rows
|
|
ORDER BY course_id, stage_order; |