diff --git a/mnoskov/postgresql/Пет-проект: Онлайн-курсы/2. Создание отчетности (витрин)/DQL_materialized_view_conversion_funnel.sql b/mnoskov/postgresql/Пет-проект: Онлайн-курсы/2. Создание отчетности (витрин)/DQL_materialized_view_conversion_funnel.sql new file mode 100644 index 0000000..6b208c0 --- /dev/null +++ b/mnoskov/postgresql/Пет-проект: Онлайн-курсы/2. Создание отчетности (витрин)/DQL_materialized_view_conversion_funnel.sql @@ -0,0 +1,114 @@ +WITH stage_courses AS ( + -- registered + (SELECT + 0 AS course_id, + 1 AS stage_id, + 'registered' AS stage_name, + count(DISTINCT u.id) AS users_count + FROM + users u) + UNION ALL + -- enrolled + (SELECT + e.course_id, + 2 AS stage_id, + 'enrolled' AS stage_name, + count(DISTINCT e.user_id) AS users_count + FROM + enrollments e + GROUP BY + e.course_id + ORDER BY + e.course_id) + UNION ALL + -- started + (SELECT + l.course_id, + 3 AS stage_id, + 'started' AS stage_name, + count(DISTINCT lv.user_id) AS users_count + FROM + lessons l + JOIN + lesson_views lv ON l.id = lv.lesson_id + GROUP BY + l.course_id + ORDER BY + l.course_id) + UNION ALL + -- mid_progress + (WITH lessons_mid AS ( + SELECT + l.course_id, + ceil(percentile_cont(0.5) WITHIN GROUP (ORDER BY l.id)) AS mid_in_lesson_id + FROM + lessons l + GROUP BY + l.course_id + ) + SELECT + lm.course_id, + 4 AS stage_id, + 'mid_progress' AS stage_name, + count(lv.user_id) AS users_count + FROM + lessons_mid lm + LEFT JOIN + lesson_views lv ON lm.mid_in_lesson_id = lv.lesson_id + GROUP BY + lm.course_id, lm.mid_in_lesson_id + ORDER BY + lm.course_id) + UNION ALL + -- completed + (WITH courses_lessons_id AS ( + SELECT + l.course_id, + l.id AS lesson_id + FROM + lessons l + GROUP BY + l.course_id, l.id + ), + lessons_numbers AS ( + SELECT + cli.course_id, + cli.lesson_id, + ROW_NUMBER() OVER(PARTITION BY cli.course_id ORDER BY cli.lesson_id DESC) AS lesson_number + FROM + courses_lessons_id cli + ) + SELECT + ln.course_id, + 5 AS stage_id, + 'completed' AS stage_name, + count(lv.user_id) AS users_count + FROM + lessons_numbers ln + LEFT JOIN + lesson_views lv ON ln.lesson_id = lv.lesson_id + WHERE + ln.lesson_number = 1 + GROUP BY + ln.course_id, ln.lesson_id + ORDER BY + ln.course_id) +) +SELECT + sc.course_id, + c.title AS course_title, + sc.stage_id, + sc.stage_name, + sc.users_count, + CASE + WHEN lag(sc.users_count) OVER (PARTITION BY sc.course_id ORDER BY sc.stage_id) IS NULL THEN 'first stage' + WHEN lag(sc.users_count) OVER (PARTITION BY sc.course_id ORDER BY sc.stage_id) = 0 THEN 0::text || '%' + WHEN lag(sc.users_count) OVER (PARTITION BY sc.course_id ORDER BY sc.stage_id) IS NOT NULL THEN round((sc.users_count / lag(sc.users_count) OVER (PARTITION BY sc.course_id ORDER BY sc.stage_id)::NUMERIC) * 100, 0)::text || '%' + END AS conversion_from_previous, + round((sc.users_count / FIRST_VALUE(sc.users_count) OVER (ORDER BY sc.stage_id)::NUMERIC) * 100, 0)::text || '%' AS conversion_from_start +FROM + courses c +RIGHT JOIN + stage_courses sc ON c.id = sc.course_id +ORDER BY + sc.course_id \ No newline at end of file