327 lines
11 KiB
SQL
327 lines
11 KiB
SQL
create table users (
|
||
id INT primary key,
|
||
name VARCHAR(50) NOT NULL,
|
||
age INT,
|
||
email VARCHAR(50) NOT NULL,
|
||
registration_date date
|
||
);
|
||
|
||
INSERT INTO users (id, name, age, email, registration_date)
|
||
VALUES
|
||
(1, 'Alice', 25, 'alice@mail.com', '2023-01-10'),
|
||
(2, 'Bob', 30, 'bob@gmail.com', '2023-02-05'),
|
||
(3, 'Charlie', 22, 'charlie@mail.com', '2023-02-20'),
|
||
(4, 'Diana', 28, 'diana@mail.com', '2023-03-01'),
|
||
(5, 'Ethan', 35, 'ethan@gmail.com', '2023-03-10'),
|
||
(6, 'Frank', 29, 'frank@mail.com', '2023-01-05'),
|
||
(7, 'Grace', 26, 'grace@gmail.com', '2023-01-12'),
|
||
(8, 'Henry', 32, 'henry@mail.com', '2023-01-20'),
|
||
(9, 'Iris', 24, 'iris@gmail.com', '2023-02-10'),
|
||
(10, 'Jack', 27, 'jack@mail.com', '2023-04-15'),
|
||
(11, 'Kelly', 23, 'kelly@gmail.com', '2023-04-20'),
|
||
(12, 'Leo', 31, 'leo@mail.com', '2023-01-15'),
|
||
(13, 'Mia', 26, 'mia@gmail.com', '2023-01-18'),
|
||
(14, 'Nina', 28, 'nina@mail.com', '2023-01-08'),
|
||
(15, 'Oscar', 33, 'oscar@gmail.com', '2023-01-10'),
|
||
(16, 'Paul', 29, 'paul@mail.com', '2023-02-15'),
|
||
(17, 'Quinn', 24, 'quinn@gmail.com', '2023-03-20'),
|
||
(18, 'Rita', 27, 'rita@mail.com', '2023-04-01'),
|
||
(19, 'Sam', 30, 'sam@gmail.com', '2023-04-10'),
|
||
(20, 'Tina', 25, 'tina@mail.com', '2023-04-18');
|
||
|
||
create table courses (
|
||
id INT primary key,
|
||
title VARCHAR(100),
|
||
category VARCHAR(50),
|
||
created_at date
|
||
);
|
||
|
||
INSERT INTO courses (id, title, category, created_at)
|
||
VALUES
|
||
(1, 'SQL для начинающих', 'data', '2023-01-01'),
|
||
(2, 'Python для анализа данных', 'programming', '2023-01-15'),
|
||
(3, 'BI с нуля', 'business', '2023-03-01'),
|
||
(4, 'Excel для аналитиков', 'business', '2023-02-01'),
|
||
(5, 'Основы машинного обучения', 'data', '2023-03-15');
|
||
|
||
|
||
create table lessons (
|
||
id INT primary key,
|
||
course_id INT,
|
||
title VARCHAR(100),
|
||
duration_min INT,
|
||
foreign key (course_id) references courses(id)
|
||
);
|
||
|
||
INSERT INTO lessons (id, course_id, title, duration_min)
|
||
VALUES
|
||
(1, 1, 'SELECT и FROM', 10),
|
||
(2, 1, 'JOIN', 15),
|
||
(3, 1, 'WHERE и фильтрация', 12),
|
||
(4, 1, 'Агрегации и GROUP BY', 18),
|
||
(5, 1, 'Подзапросы', 25),
|
||
(6, 2, 'Pandas основы', 20),
|
||
(7, 2, 'NumPy', 15),
|
||
(8, 2, 'Визуализация данных', 22),
|
||
(9, 3, 'Основы BI', 12),
|
||
(10, 3, 'Метрики и дашборды', 18),
|
||
(11, 3, 'Power BI введение', 20),
|
||
(12, 4, 'Формулы в Excel', 15),
|
||
(13, 4, 'Сводные таблицы', 18),
|
||
(14, 4, 'Графики и диаграммы', 14),
|
||
(15, 5, 'Введение в ML', 20),
|
||
(16, 5, 'Линейная регрессия', 30),
|
||
(17, 5, 'Классификация', 28),
|
||
(18, 5, 'Кластеризация', 25);
|
||
|
||
create table enrollments (
|
||
id INT primary key,
|
||
user_id INT,
|
||
course_id INT,
|
||
enrolled_at date,
|
||
foreign key (user_id) references users(id),
|
||
foreign key (course_id) references courses(id)
|
||
);
|
||
|
||
INSERT INTO enrollments (id, user_id, course_id, enrolled_at)
|
||
VALUES
|
||
(1, 1, 1, '2023-01-15'),
|
||
(2, 1, 2, '2023-02-01'),
|
||
(3, 2, 1, '2023-01-20'),
|
||
(4, 3, 2, '2023-03-05'),
|
||
(5, 4, 3, '2023-04-01'),
|
||
(6, 6, 1, '2023-01-06'),
|
||
(7, 6, 2, '2023-01-10'),
|
||
(8, 6, 4, '2023-02-05'),
|
||
(9, 7, 1, '2023-01-13'),
|
||
(10, 7, 3, '2023-03-10'),
|
||
(11, 8, 1, '2023-01-22'),
|
||
(12, 8, 2, '2023-01-22'),
|
||
(13, 8, 3, '2023-01-22'),
|
||
(14, 9, 4, '2023-02-12'),
|
||
(15, 10, 1, '2023-04-16'),
|
||
(16, 11, 2, '2023-04-21'),
|
||
(17, 12, 1, '2023-01-16'),
|
||
(18, 13, 2, '2023-01-19'),
|
||
(19, 13, 4, '2023-02-20'),
|
||
(20, 14, 1, '2023-01-09'),
|
||
(21, 14, 2, '2023-01-09'),
|
||
(22, 14, 3, '2023-01-09'),
|
||
(23, 14, 4, '2023-02-01'),
|
||
(24, 14, 5, '2023-03-20'),
|
||
(25, 15, 1, '2023-01-11'),
|
||
(26, 15, 3, '2023-03-05'),
|
||
(27, 16, 2, '2023-02-16'),
|
||
(28, 16, 4, '2023-02-16'),
|
||
(29, 17, 3, '2023-03-22'),
|
||
(30, 17, 5, '2023-03-25'),
|
||
(31, 18, 1, '2023-04-02'),
|
||
(32, 19, 1, '2023-04-11'),
|
||
(33, 19, 2, '2023-04-11'),
|
||
(34, 20, 2, '2023-04-19'),
|
||
(35, 5, 5, '2023-03-20'),
|
||
(36, 1, 4, '2023-02-10'),
|
||
(37, 2, 3, '2023-03-15'),
|
||
(38, 3, 1, '2023-02-25'),
|
||
(39, 4, 2, '2023-03-10'),
|
||
(40, 6, 3, '2023-03-08'),
|
||
(41, 7, 2, '2023-02-01'),
|
||
(42, 9, 1, '2023-02-15'),
|
||
(43, 12, 3, '2023-03-10'),
|
||
(44, 15, 2, '2023-02-01'),
|
||
(45, 18, 4, '2023-04-05');
|
||
|
||
create table lesson_views (
|
||
id INT primary key,
|
||
user_id INT,
|
||
lesson_id INT,
|
||
viewed_at timestamp,
|
||
foreign key (user_id) references users(id),
|
||
foreign key (lesson_id) references lessons(id)
|
||
);
|
||
|
||
INSERT INTO lesson_views (id, user_id, lesson_id, viewed_at)
|
||
VALUES
|
||
(1, 1, 1, '2023-01-16 10:00:00'),
|
||
(2, 1, 2, '2023-01-16 10:15:00'),
|
||
(3, 1, 3, '2023-01-17 09:00:00'),
|
||
(4, 1, 4, '2023-01-17 09:30:00'),
|
||
(5, 1, 4, '2023-01-17 11:00:00'),
|
||
(6, 1, 4, '2023-01-18 10:00:00'),
|
||
(7, 1, 6, '2023-02-02 14:00:00'),
|
||
(8, 1, 12, '2023-02-15 10:00:00'),
|
||
(9, 1, 13, '2023-02-15 10:30:00'),
|
||
(10, 2, 1, '2023-01-21 09:00:00'),
|
||
(11, 2, 9, '2023-03-16 10:00:00'),
|
||
(12, 2, 10, '2023-03-16 10:30:00'),
|
||
(13, 3, 6, '2023-03-06 12:00:00'),
|
||
(14, 3, 1, '2023-02-26 11:00:00'),
|
||
(15, 3, 2, '2023-02-26 11:20:00'),
|
||
(16, 4, 9, '2023-04-02 10:00:00'),
|
||
(17, 4, 10, '2023-04-03 10:00:00'),
|
||
(18, 4, 6, '2023-03-12 14:00:00'),
|
||
(19, 4, 7, '2023-03-13 09:00:00'),
|
||
(20, 5, 15, '2023-03-21 10:00:00'),
|
||
(21, 5, 16, '2023-03-22 11:00:00'),
|
||
(22, 6, 1, '2023-01-07 10:00:00'),
|
||
(23, 6, 2, '2023-01-07 10:15:00'),
|
||
(24, 6, 3, '2023-01-08 09:00:00'),
|
||
(25, 6, 4, '2023-01-08 09:30:00'),
|
||
(26, 6, 5, '2023-01-09 10:00:00'),
|
||
(27, 6, 6, '2023-01-11 14:00:00'),
|
||
(28, 6, 7, '2023-01-12 10:00:00'),
|
||
(29, 6, 8, '2023-01-13 11:00:00'),
|
||
(30, 6, 12, '2023-02-06 09:00:00'),
|
||
(31, 6, 13, '2023-02-06 09:30:00'),
|
||
(32, 6, 14, '2023-02-07 10:00:00'),
|
||
(33, 6, 9, '2023-03-09 11:00:00'),
|
||
(34, 7, 1, '2023-01-14 10:00:00'),
|
||
(35, 7, 2, '2023-01-14 10:20:00'),
|
||
(36, 7, 3, '2023-01-15 09:00:00'),
|
||
(37, 7, 9, '2023-03-11 14:00:00'),
|
||
(38, 7, 10, '2023-03-11 14:30:00'),
|
||
(39, 9, 12, '2023-02-13 10:00:00'),
|
||
(40, 9, 13, '2023-02-13 10:30:00'),
|
||
(41, 9, 1, '2023-02-16 11:00:00'),
|
||
(42, 12, 1, '2023-01-17 10:00:00'),
|
||
(43, 12, 2, '2023-01-17 10:20:00'),
|
||
(44, 12, 1, '2023-04-10 11:00:00'),
|
||
(45, 12, 3, '2023-04-10 11:30:00'),
|
||
(46, 12, 9, '2023-03-12 10:00:00'),
|
||
(47, 13, 6, '2023-01-20 14:00:00'),
|
||
(48, 13, 7, '2023-01-21 10:00:00'),
|
||
(49, 13, 12, '2023-02-21 09:00:00'),
|
||
(50, 14, 1, '2023-01-09 08:00:00'),
|
||
(51, 14, 2, '2023-01-09 08:15:00'),
|
||
(52, 14, 3, '2023-01-10 10:00:00'),
|
||
(53, 14, 4, '2023-01-10 10:30:00'),
|
||
(54, 14, 5, '2023-01-11 09:00:00'),
|
||
(55, 14, 6, '2023-01-10 14:00:00'),
|
||
(56, 14, 7, '2023-01-11 10:00:00'),
|
||
(57, 14, 8, '2023-01-12 11:00:00'),
|
||
(58, 14, 9, '2023-01-10 08:00:00');
|
||
|
||
|
||
---------------------------------------------------------
|
||
-- 1 задание Активные пользователи
|
||
|
||
create materialized view user_activity_summary AS
|
||
with enroll_count as (
|
||
select u.id as user_id, u.name as user_name,
|
||
COUNT(e.course_id) as enrollment_count
|
||
from users u
|
||
join enrollments e on u.id = e.user_id
|
||
group by u.id, u.name
|
||
),
|
||
viewed_count as (
|
||
select ec.user_id, ec.user_name, enrollment_count,
|
||
COUNT(distinct lv.lesson_id) as viewed_lessons_count,
|
||
MIN(lv.viewed_at) as first_view,
|
||
MAX(lv.viewed_at) as last_view
|
||
from enroll_count ec
|
||
left join lesson_views lv on ec.user_id = lv.user_id
|
||
group by ec.user_id, ec.user_name, enrollment_count
|
||
),
|
||
possible_lessons as (
|
||
select u.id as user_id, COUNT(l.id) as poss_lessons
|
||
from users u
|
||
left join enrollments e on u.id = e.user_id
|
||
left join lessons l on e.course_id = l.course_id
|
||
group by u.id
|
||
)
|
||
select vc.user_id, user_name, enrollment_count, viewed_lessons_count, first_view, last_view,
|
||
ROUND(100.0 * viewed_lessons_count / pl.poss_lessons, 2) as engagement_rate
|
||
from viewed_count vc
|
||
left join possible_lessons pl on vc.user_id = pl.user_id
|
||
;
|
||
|
||
------------------------------------------------------------------------------------------------------------------
|
||
-- 2 задание Эффективность курсов
|
||
|
||
create materialized view course_summary AS
|
||
with lessons_per_course as (
|
||
select c.id as course_id, c.title as course_title,
|
||
COUNT(distinct e.user_id) as unique_users,
|
||
COUNT(distinct l.id) as lessons_count
|
||
from courses c
|
||
left join enrollments e on c.id = e.course_id
|
||
join lessons l on e.course_id = l.course_id
|
||
group by c.id, c.title
|
||
),
|
||
course_views as (
|
||
select l.course_id, COUNT(lv.id) as total_views
|
||
from lesson_views lv
|
||
join lessons l on lv.lesson_id = l.id
|
||
group by l.course_id
|
||
),
|
||
view_date as (
|
||
select l.course_id,
|
||
MIN(lv.viewed_at) as first_viewed_at,
|
||
MAX(lv.viewed_at) as last_viewed_at
|
||
from lessons l
|
||
join lesson_views lv on l.id = lv.lesson_id
|
||
group by l.course_id
|
||
)
|
||
select lpc.course_id, lpc.course_title, lpc.unique_users, lpc.lessons_count,
|
||
ROUND(1.00 * cv.total_views / lpc.unique_users, 2) as avg_views_per_user,
|
||
vd.first_viewed_at,
|
||
vd.last_viewed_at
|
||
from lessons_per_course lpc
|
||
join course_views cv on lpc.course_id = cv.course_id
|
||
left join view_date vd on cv.course_id = vd.course_id
|
||
order by course_id
|
||
;
|
||
|
||
--------------------------------------------------------------------------------------------------
|
||
-- 3 задание Общая отчетность по взаимодействию
|
||
create materialized view platform_summary as
|
||
with total_counts as (
|
||
select COUNT(id) as total_users,
|
||
(select COUNT(id) from courses) as total_courses,
|
||
(select COUNT(id) from lessons) as total_lessons,
|
||
(select COUNT(id) from lesson_views) as total_views,
|
||
(select COUNT(distinct user_id) from lesson_views) as users_with_views
|
||
from users
|
||
)
|
||
SELECT total_users, total_courses, total_lessons, users_with_views,
|
||
ROUND(1.00 * total_lessons / total_courses, 2) as avg_lessons_per_course,
|
||
ROUND(1.00 * total_views / total_lessons, 2) as avg_views_per_lesson
|
||
from total_counts
|
||
;
|
||
|
||
-----------------------------------------------------------------------------------------------------
|
||
-- 4 Задание Когортный анализ пользователей
|
||
create materialized view user_cohort_analysis AS
|
||
with needed_users as (
|
||
select distinct u.id as user_id, u.registration_date as reg_date, e.course_id, lv.id as view_id,
|
||
lv.lesson_id as viewed_lesson_id,
|
||
FIRST_VALUE(lv.viewed_at) over (partition by lv.user_id order by lv.viewed_at) as first_view_date,
|
||
e.user_id as enrolled_users,
|
||
lv.user_id as active_users
|
||
from users u
|
||
left join enrollments e on u.id = e.user_id
|
||
left join lesson_views lv on e.user_id = lv.user_id
|
||
order by user_id
|
||
),
|
||
CTE as (
|
||
select
|
||
TO_CHAR(reg_date, 'YYYY-MM') as cohort_month,
|
||
COUNT(distinct user_id) as users_in_cohort,
|
||
COUNT(distinct enrolled_users) as enrolled_users,
|
||
COUNT(distinct active_users) as active_users,
|
||
COUNT(course_id) as courses_count,
|
||
extract('days' from AVG(first_view_date - reg_date)) as avg_time_to_first_view
|
||
from needed_users
|
||
where date_trunc('month', reg_date)::date = '2023-03-01'
|
||
group by cohort_month
|
||
)
|
||
select cohort_month, users_in_cohort, enrolled_users, active_users,
|
||
ROUND(100.0 * active_users / users_in_cohort, 2) as retention_rate,
|
||
courses_count / users_in_cohort as avg_courses_per_user,
|
||
avg_time_to_first_view
|
||
from CTE
|
||
;
|
||
|
||
|
||
|