Merge branch 'main' into OS-412
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
CREATE MATERIALIZED VIEW platform_summary AS
|
||||||
|
with users_counts as (
|
||||||
|
select
|
||||||
|
COUNT(distinct u.id) as total_users,
|
||||||
|
COUNT(distinct lv.user_id) as users_with_views
|
||||||
|
from users u
|
||||||
|
left join lesson_views lv on lv.user_id = u.id
|
||||||
|
),
|
||||||
|
courses_lessons_count as (
|
||||||
|
select COUNT(distinct c.id) as total_courses,
|
||||||
|
COUNT(distinct l.id) as total_lessons
|
||||||
|
from courses c
|
||||||
|
left join lessons l on l.course_id = c.id
|
||||||
|
),
|
||||||
|
views_count as (
|
||||||
|
select COUNT(distinct lv.lesson_id) as lessons_with_views,
|
||||||
|
COUNT(distinct lv.id) as total_views
|
||||||
|
from lesson_views lv
|
||||||
|
)
|
||||||
|
select uc.total_users, clc.total_courses, clc.total_lessons, uc.users_with_views,
|
||||||
|
ROUND(1.00 * clc.total_lessons / nullif(clc.total_courses, 0), 2) as avg_lessons_per_course,
|
||||||
|
ROUND(1.00 * vc.total_views / nullif(clc.total_lessons, 0), 2) as avg_views_per_lesson
|
||||||
|
from users_counts uc
|
||||||
|
cross join courses_lessons_count clc
|
||||||
|
cross join views_count vc
|
||||||
|
;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
CREATE MATERIALIZED VIEW users_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
|
||||||
|
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 case when user_id in (select user_id from enrollments) then user_id end) as enrolled_users,
|
||||||
|
COUNT(distinct case when user_id in (select user_id from lesson_views) then user_id end) 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
|
||||||
|
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::numeric / users_in_cohort as avg_courses_per_user,
|
||||||
|
avg_time_to_first_view
|
||||||
|
from CTE
|
||||||
|
;
|
||||||
@@ -0,0 +1,466 @@
|
|||||||
|
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,
|
||||||
|
MIN(lv.viewed_at) as first_viewed_at,
|
||||||
|
MAX(lv.viewed_at) as last_viewed_at
|
||||||
|
from lesson_views lv
|
||||||
|
join lessons l on lv.lesson_id = l.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,
|
||||||
|
cv.first_viewed_at,
|
||||||
|
cv.last_viewed_at
|
||||||
|
from lessons_per_course lpc
|
||||||
|
join course_views cv on lpc.course_id = cv.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
|
||||||
|
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
|
||||||
|
;
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- 5 Задание Популярность курсов
|
||||||
|
create materialized view lesson_popularity_ranking as
|
||||||
|
with lessons_in_courses as (
|
||||||
|
select l.id as lesson_id, l.title as lesson_title, c.title as course_title,
|
||||||
|
COUNT(e.user_id) as enrolled_users
|
||||||
|
from lessons l
|
||||||
|
join courses c on l.course_id = c.id
|
||||||
|
join enrollments e on e.course_id = c.id
|
||||||
|
group by l.id, l.title, c.title
|
||||||
|
order by lesson_id
|
||||||
|
),
|
||||||
|
views_cte as (
|
||||||
|
select lic.lesson_id,
|
||||||
|
COUNT(lv.id) as total_views,
|
||||||
|
COUNT(distinct lv.user_id) as unique_viewers,
|
||||||
|
1.00 * COUNT(lv.id) / nullif(COUNT(distinct lv.user_id), 0) as avg_views_per_user,
|
||||||
|
COUNT(lic.enrolled_users) as enrolled_to_course
|
||||||
|
from lessons_in_courses lic
|
||||||
|
left join lesson_views lv on lic.lesson_id = lv.lesson_id
|
||||||
|
group by lic.lesson_id
|
||||||
|
)
|
||||||
|
select lic.lesson_id, lic.lesson_title, lic.course_title,
|
||||||
|
vc.total_views,
|
||||||
|
vc.unique_viewers,
|
||||||
|
coalesce(vc.avg_views_per_user, 0) as avg_views_per_user,
|
||||||
|
dense_rank() OVER (ORDER BY vc.total_views desc) as popularity_rank,
|
||||||
|
ROUND(100.0 * unique_viewers / enrolled_to_course, 2) as completion_rate
|
||||||
|
from lessons_in_courses lic
|
||||||
|
join views_cte vc on lic.lesson_id = vc.lesson_id
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------------------------------------
|
||||||
|
-- 6 Задания Воронка Конверсии
|
||||||
|
create materialized view conversion_funnel AS
|
||||||
|
with course_lessons as (
|
||||||
|
select c.id as course_id, c.title as course_title,
|
||||||
|
COUNT(l.id) as total_lessons
|
||||||
|
from courses c
|
||||||
|
join lessons l on l.course_id = c.id
|
||||||
|
group by c.id, c.title
|
||||||
|
),
|
||||||
|
registered_users as (
|
||||||
|
select COUNT(distinct id) as total_users
|
||||||
|
from users
|
||||||
|
),
|
||||||
|
enrolled_users as (
|
||||||
|
select e.course_id,
|
||||||
|
COUNT(distinct e.user_id) as enrolled_count
|
||||||
|
from enrollments e
|
||||||
|
group by e.course_id
|
||||||
|
),
|
||||||
|
started_users as (
|
||||||
|
select l.course_id,
|
||||||
|
COUNT(distinct lv.user_id) as started_count
|
||||||
|
from lessons l
|
||||||
|
join lesson_views lv on l.id = lv.lesson_id
|
||||||
|
group by l.course_id
|
||||||
|
),
|
||||||
|
user_progress as (
|
||||||
|
select l.course_id, lv.user_id,
|
||||||
|
COUNT(distinct lv.lesson_id) as viewed_lessons
|
||||||
|
from lesson_views lv
|
||||||
|
join lessons l on lv.lesson_id = l.id
|
||||||
|
group by l.course_id, lv.user_id
|
||||||
|
),
|
||||||
|
mid_progress_users as (
|
||||||
|
select up.course_id,
|
||||||
|
COUNT(distinct up.user_id) as mid_progress_count
|
||||||
|
from user_progress up
|
||||||
|
join course_lessons cl on up.course_id = cl.course_id
|
||||||
|
where up.viewed_lessons >= cl.total_lessons * 0.5
|
||||||
|
group by up.course_id
|
||||||
|
),
|
||||||
|
completed_users as (
|
||||||
|
select up.course_id,
|
||||||
|
COUNT(distinct up.user_id) as completed_count
|
||||||
|
from user_progress up
|
||||||
|
join course_lessons cl on up.course_id = cl.course_id
|
||||||
|
where up.viewed_lessons >= cl.total_lessons
|
||||||
|
group by up.course_id
|
||||||
|
),
|
||||||
|
funnel_stages as (
|
||||||
|
select cl.course_id, cl.course_title,
|
||||||
|
'registered' as stage_name,
|
||||||
|
ru.total_users as users_count,
|
||||||
|
1 as stage_order
|
||||||
|
from course_lessons cl
|
||||||
|
cross join registered_users ru
|
||||||
|
union all
|
||||||
|
select cl.course_id, cl.course_title,
|
||||||
|
'enrolled' as stage_name,
|
||||||
|
eu.enrolled_count as users_count,
|
||||||
|
2 as stage_order
|
||||||
|
from course_lessons cl
|
||||||
|
left join enrolled_users eu on cl.course_id = eu.course_id
|
||||||
|
union all
|
||||||
|
select cl.course_id, cl.course_title,
|
||||||
|
'started' as stage_name,
|
||||||
|
su.started_count as users_count,
|
||||||
|
3 as stage_order
|
||||||
|
from course_lessons cl
|
||||||
|
left join started_users su on cl.course_id = su.course_id
|
||||||
|
union all
|
||||||
|
select cl.course_id, cl.course_title,
|
||||||
|
'mid_progress' as stage_name,
|
||||||
|
coalesce(mpu.mid_progress_count, 0) as users_count,
|
||||||
|
4 as stage_order
|
||||||
|
from course_lessons cl
|
||||||
|
left join mid_progress_users mpu on cl.course_id = mpu.course_id
|
||||||
|
union all
|
||||||
|
select cl.course_id, cl.course_title,
|
||||||
|
'completed' as stage_name,
|
||||||
|
coalesce(cu.completed_count, 0) as users_count,
|
||||||
|
5 as stage_order
|
||||||
|
from course_lessons cl
|
||||||
|
left join completed_users cu on cl.course_id = cu.course_id
|
||||||
|
)
|
||||||
|
select course_id, course_title, stage_name, users_count,
|
||||||
|
ROUND(100.0 * users_count / NULLIF(LAG(users_count) over (partition by course_id order by stage_order), 0), 2)
|
||||||
|
as conversion_from_previous,
|
||||||
|
ROUND(100.0 * users_count / NULLIF(FIRST_VALUE(users_count) over (partition by course_id order by stage_order), 0), 2)
|
||||||
|
as conversion_from_start
|
||||||
|
from funnel_stages
|
||||||
|
;
|
||||||
|
-- Признаюсь 6-е задание сделал с помощью нейросети, потому что сам вообще никак к нему подобраться не мог.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Доп. Задание №1 Анализ drop-off точек
|
||||||
|
select course_id, stage_name, users_count,
|
||||||
|
100 - conversion_from_previous as lost_precentage
|
||||||
|
from conversion_funnel
|
||||||
|
where stage_name = 'started'
|
||||||
|
order by lost_precentage desc
|
||||||
|
;
|
||||||
|
--------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Доп. Задание №2 Топ-3 урока с повторными просмотрами
|
||||||
|
select lesson_id
|
||||||
|
from lesson_popularity_ranking
|
||||||
|
where avg_views_per_user > 1
|
||||||
|
limit 3
|
||||||
|
;
|
||||||
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Доп. Задание №3 Лучшая когорта по retention
|
||||||
|
select cohort_month, retention_rate
|
||||||
|
from user_cohort_analysis
|
||||||
|
order by retention_rate desc
|
||||||
|
limit 2
|
||||||
|
;
|
||||||
|
-- В нашем случае два месяца с одинаковыми лучшими показателями retention это 2023-01 и 2023-02. Это является следствием того, что у нас
|
||||||
|
-- наибольшее количество зарегистрированных пользователей именно в эти месяцы, а именно 2023-01 = 40%, а 2023-02 = 20%, соотвественно 60% пользователей были зарегистрированы в эти месяцы.
|
||||||
@@ -0,0 +1,525 @@
|
|||||||
|
-----------------------------------------------------------
|
||||||
|
--DDL
|
||||||
|
create table users (
|
||||||
|
id INT primary key not null,
|
||||||
|
name VARCHAR(100),
|
||||||
|
age INT,
|
||||||
|
email VARCHAR(100),
|
||||||
|
country VARCHAR(50),
|
||||||
|
is_active BOOLEAN,
|
||||||
|
created_at DATE
|
||||||
|
);
|
||||||
|
|
||||||
|
create table products (
|
||||||
|
id INT primary key,
|
||||||
|
name VARCHAR(100) not null,
|
||||||
|
category VARCHAR(50),
|
||||||
|
price DECIMAL(10, 2) not null,
|
||||||
|
in_stock BOOLEAN
|
||||||
|
);
|
||||||
|
|
||||||
|
create table orders (
|
||||||
|
id INT primary key,
|
||||||
|
user_id INT,
|
||||||
|
order_date DATE not null,
|
||||||
|
status VARCHAR(20)
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table order_items (
|
||||||
|
order_id INT,
|
||||||
|
product_id INT,
|
||||||
|
quantity INT not null,
|
||||||
|
price_at_purchase DECIMAL(10, 2) not null,
|
||||||
|
primary key (order_id, product_id)
|
||||||
|
FOREIGN KEY ()
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table users
|
||||||
|
alter column created_at type timestamptz;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------
|
||||||
|
-- DML
|
||||||
|
INSERT INTO users (id, name, age, email, country, is_active, created_at)
|
||||||
|
VALUES
|
||||||
|
(1, 'Alice', 25, 'alice@example.com', 'US', true, '2024-01-10 10:00:00'),
|
||||||
|
(2, 'Bob', 30, 'bob@example.com', 'UK', true, '2024-02-05 09:30:00'),
|
||||||
|
(3, 'Carol', 27, 'carol@example.com', 'US', false, '2024-03-01 15:20:00'),
|
||||||
|
(4, 'Diana', 22, 'diana@GMAIL.com', 'US', true, '2024-01-12 08:15:00'),
|
||||||
|
(5, 'Evan', 35, 'EVAN@example.com', 'UK', true, '2024-01-18 19:40:00'),
|
||||||
|
(6, 'Farida', 29, 'farida@example.com', 'KZ', true, '2024-02-20 11:05:00'),
|
||||||
|
(7, 'George', 31, 'george+test@example.com', 'US', true, '2024-03-05 16:45:00'),
|
||||||
|
(8, 'Helen', 24, NULL, 'UK', false, '2024-03-06 08:20:00'),
|
||||||
|
(9, 'Ivan', 26, 'ivan@example.com', 'RU', true, '2024-01-11 14:30:00'),
|
||||||
|
(10, 'Julia', 28, 'julia@example.com', 'US', true, '2024-03-07 18:05:00');
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO products (id, name, category, price, in_stock)
|
||||||
|
VALUES
|
||||||
|
(1, 'iPhone 15', 'Электроника', 80000, true),
|
||||||
|
(2, 'Kindle', 'Электроника', 15000, true),
|
||||||
|
(3, 'Кроссовки Nike', 'Одежда', 9000, true),
|
||||||
|
(4, 'Кроссовки NoName', 'Одежда', 3000, false),
|
||||||
|
(5, 'Наушники Pro', 'Электроника', 12000, true),
|
||||||
|
(6, 'Фитнес‑браслет', 'Гаджеты', 6000, true),
|
||||||
|
(7, 'Подарочная карта', 'Сервисы', 1000, true);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO orders (id, user_id, order_date, status)
|
||||||
|
VALUES
|
||||||
|
(1, 1, '2025-01-10 12:00:00', 'paid'),
|
||||||
|
(2, 3, '2025-01-12 09:30:00', 'cancelled'),
|
||||||
|
(3, 1, '2025-01-15 18:20:00', 'paid'),
|
||||||
|
(4, 2, '2025-01-20 11:05:00', 'created'),
|
||||||
|
(5, 4, '2025-02-01 17:45:00', 'paid'),
|
||||||
|
(6, 5, '2025-02-10 10:10:00', 'refunded'),
|
||||||
|
(7, 7, '2025-03-01 09:00:00', 'paid'),
|
||||||
|
(8, 9, '2025-03-05 19:30:00', 'paid');
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO order_items (order_id, product_id, quantity, price_at_purchase)
|
||||||
|
VALUES
|
||||||
|
(1, 1, 1, 78000),
|
||||||
|
(1, 3, 2, 8500),
|
||||||
|
(2, 2, 1, 14000),
|
||||||
|
(3, 5, 1, 11000),
|
||||||
|
(3, 7, 1, 1000),
|
||||||
|
(4, 2, 1, 15000),
|
||||||
|
(5, 6, 1, 6000),
|
||||||
|
(6, 1, 1, 82000),
|
||||||
|
(7, 3, 1, 9000),
|
||||||
|
(8, 4, 2, 2800);
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
--BASE SQL
|
||||||
|
select id, name, country, created_at, email from users
|
||||||
|
order by created_at desc, name;
|
||||||
|
|
||||||
|
select id, name, country from users
|
||||||
|
where country = 'US' -- 'UK'
|
||||||
|
order by name;
|
||||||
|
|
||||||
|
select id, name, email from users
|
||||||
|
where email is not null
|
||||||
|
order by name;
|
||||||
|
|
||||||
|
select distinct LOWER(email) as email_lower from users
|
||||||
|
where email is not null;
|
||||||
|
|
||||||
|
select id, name, created_at from users
|
||||||
|
where created_at > '2024-01-11'
|
||||||
|
order by created_at desc
|
||||||
|
limit 2 offset 1;
|
||||||
|
------------------------------------------------------------------------------------------------------
|
||||||
|
-- FILTRATION
|
||||||
|
select name, category, price,
|
||||||
|
price * 1.3 as price_with_markup,
|
||||||
|
price * 1.5 as price_with_vat from products
|
||||||
|
where in_stock is true
|
||||||
|
and category not in ('Гаджеты')
|
||||||
|
and price >= 100 and price <=1300;
|
||||||
|
|
||||||
|
select name, price,
|
||||||
|
price * 0.85 as price_with_discount
|
||||||
|
from products
|
||||||
|
where price < 100 or price > 1000;
|
||||||
|
|
||||||
|
select id, name, category, price from products
|
||||||
|
where category in ('Электроника') and price >= 15000;
|
||||||
|
|
||||||
|
select name, category, price from products
|
||||||
|
where name not like '%iPhone%';
|
||||||
|
|
||||||
|
select * from products
|
||||||
|
where name ilike '%pro%';
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
-- JOIN
|
||||||
|
-- 1 задание
|
||||||
|
select o.id as order_id, order_date, status, u.name as user_name, country from orders o
|
||||||
|
join users u on o.user_id = u.id;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
|
||||||
|
select o.id as order_id, p.name as product_name, oi.quantity, oi.price_at_purchase from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
join products p on oi.product_id = p.id
|
||||||
|
where o.id = 1;
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
select o.id as order_id, p.name as product_name, oi.quantity, oi.price_at_purchase from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
join products p on oi.product_id = p.id;
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
select u.name as user_name, o.id as order_id, o.status from users u
|
||||||
|
left join orders o on u.id = o.user_id;
|
||||||
|
|
||||||
|
-- 5 задание
|
||||||
|
select u.id as user_id, u.name as user_name from users u
|
||||||
|
left join orders o on u.id = o.user_id
|
||||||
|
where o.user_id is null;
|
||||||
|
|
||||||
|
-- 6 задание
|
||||||
|
|
||||||
|
select o.id as order_id, p.name as product_name, oi.quantity, oi.price_at_purchase from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
join products p on oi.product_id = p.id
|
||||||
|
where p.name = 'Фитнес‑браслет';
|
||||||
|
|
||||||
|
-- 7 задание
|
||||||
|
|
||||||
|
select o.id as order_id, p.name as product_name, oi.quantity, oi.price_at_purchase from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
join products p on oi.product_id = p.id
|
||||||
|
where o.status = 'paid';
|
||||||
|
|
||||||
|
-- 8 задание
|
||||||
|
|
||||||
|
select o.id, o.order_date, p.name as product_name, oi.quantity, oi.price_at_purchase from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
join products p on oi.product_id = p.id
|
||||||
|
where o.user_id in (select id from users where name = 'Alice');
|
||||||
|
|
||||||
|
-- 9 задание
|
||||||
|
|
||||||
|
select o.id as order_id, o.user_id, o.status from orders o
|
||||||
|
left join order_items oi on o.id = oi.order_id
|
||||||
|
where oi.product_id is null; -- таких у нас заказов нет, во всех заказах есть товары.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------
|
||||||
|
-- UNION
|
||||||
|
-- 1 задание
|
||||||
|
select id, name, is_active from users
|
||||||
|
where is_active is false
|
||||||
|
union
|
||||||
|
select id, name, is_active from users
|
||||||
|
where is_active is true
|
||||||
|
order by name;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
select id as order_id, user_id, order_date,
|
||||||
|
case when o.order_date < '2025-02-01' then 'old' else 'new' end as period
|
||||||
|
from orders o;
|
||||||
|
-- 3е задание не имеет смысла, т.к. все заказы покупались, там нечего соединять
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------
|
||||||
|
-- Agregation
|
||||||
|
-- 1 задание
|
||||||
|
select category, COUNT(*) as products_count from products
|
||||||
|
group by category
|
||||||
|
order by products_count desc;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
select order_id, SUM(quantity) as total_quantity, SUM(quantity * price_at_purchase) as order_revenue from order_items
|
||||||
|
group by order_id
|
||||||
|
order by order_revenue desc;
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
select p.category, SUM(oi.quantity * oi.price_at_purchase) as category_revenue from products p
|
||||||
|
join order_items oi on oi.product_id = p.id
|
||||||
|
group by p.category
|
||||||
|
order by category_revenue desc;
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
select order_id, SUM(quantity * price_at_purchase) as order_revenue from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
where o.status = 'paid'
|
||||||
|
group by oi.order_id
|
||||||
|
order by order_revenue desc;
|
||||||
|
|
||||||
|
-- 5 задание
|
||||||
|
select p.category, SUM(oi.quantity * oi.price_at_purchase) as category_revenue from products p
|
||||||
|
join order_items oi on oi.product_id = p.id
|
||||||
|
group by p.category
|
||||||
|
having SUM(oi.quantity * oi.price_at_purchase) > 1000
|
||||||
|
order by category_revenue desc;
|
||||||
|
|
||||||
|
-- 6 задание
|
||||||
|
select country, COUNT(*) as active_users_count
|
||||||
|
from users
|
||||||
|
where is_active is true
|
||||||
|
group by country
|
||||||
|
having COUNT(*) >= 2
|
||||||
|
order by active_users_count desc;
|
||||||
|
|
||||||
|
-- 7 задание
|
||||||
|
select p.name, SUM(oi.quantity) as total_quantity_sold from products p
|
||||||
|
join order_items oi on oi.product_id = p.id
|
||||||
|
group by p.name
|
||||||
|
order by total_quantity_sold desc
|
||||||
|
limit 3;
|
||||||
|
|
||||||
|
-- 8 задание
|
||||||
|
|
||||||
|
select order_id, SUM(quantity * price_at_purchase) as order_revenue
|
||||||
|
from order_items
|
||||||
|
group by order_id
|
||||||
|
having SUM(quantity * price_at_purchase) < 10000 -- сделал меньше 10000 потому что заказов дешевле 100 нет.
|
||||||
|
order by order_revenue;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------
|
||||||
|
--Functions:date strings logic
|
||||||
|
-- 1 задание
|
||||||
|
select name,
|
||||||
|
created_at::date as created_date,
|
||||||
|
CURRENT_DATE - created_at::date as days_since_registration
|
||||||
|
from users
|
||||||
|
where CURRENT_DATE - created_at::date > 750
|
||||||
|
order by days_since_registration desc;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
select name, LOWER(email) as email_clean,
|
||||||
|
substring(LOWER(email) from position('@' in email) + 1) as domain
|
||||||
|
from users
|
||||||
|
where email is not null
|
||||||
|
order by domain, name;
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
select name, age,
|
||||||
|
case when age < 20 then 'young'
|
||||||
|
when age between 20 and 30 then 'adult'
|
||||||
|
else 'senior'
|
||||||
|
end as age_group
|
||||||
|
from users
|
||||||
|
order by age;
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
with CTE as
|
||||||
|
(select name, created_at::date,
|
||||||
|
current_date - created_at::date as days_since_registration,
|
||||||
|
case when is_active = true then 'hot'
|
||||||
|
when current_date - created_at::date < 30 then 'hot'
|
||||||
|
else 'regular'
|
||||||
|
end as hot_flag
|
||||||
|
from users)
|
||||||
|
select * from CTE
|
||||||
|
where hot_flag = 'hot';
|
||||||
|
|
||||||
|
-- 5 задание
|
||||||
|
with CTE as
|
||||||
|
(select count(id) as total_users,
|
||||||
|
COUNT(email) as with_email,
|
||||||
|
(select count(*) from users where email is null) as without_email
|
||||||
|
from users)
|
||||||
|
select total_users, with_email, without_email,
|
||||||
|
ROUND(100.0 * without_email / total_users, 2) as percentage_no_email
|
||||||
|
from CTE;
|
||||||
|
|
||||||
|
-- 6 задание
|
||||||
|
select name,
|
||||||
|
CURRENT_DATE - created_at::date as days_since_registration,
|
||||||
|
case
|
||||||
|
when CURRENT_DATE - created_at::date <= 720 then 'new'
|
||||||
|
when CURRENT_DATE - created_at::date BETWEEN 721 and 750 then 'middle'
|
||||||
|
else 'old'
|
||||||
|
end as tenure_group
|
||||||
|
from users
|
||||||
|
order by days_since_registration;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------
|
||||||
|
--Subquery/CTE
|
||||||
|
-- 1 задание
|
||||||
|
select name
|
||||||
|
from users
|
||||||
|
where id in (select distinct user_id from orders)
|
||||||
|
order by name;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
select id, name, email
|
||||||
|
from users u
|
||||||
|
where not exists (
|
||||||
|
select user_id
|
||||||
|
from orders o
|
||||||
|
where o.user_id = u.id)
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
select name,
|
||||||
|
(select COUNT(*) orders_count from orders o
|
||||||
|
where o.user_id = u.id)
|
||||||
|
from users u
|
||||||
|
order by orders_count desc, name;
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
with CTE as (
|
||||||
|
select user_id, SUM(quantity * price_at_purchase) as total_revenue
|
||||||
|
from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
group by user_id
|
||||||
|
)
|
||||||
|
select u.name, c.total_revenue from users u
|
||||||
|
join CTE c on u.id = c.user_id
|
||||||
|
order by c.total_revenue desc;
|
||||||
|
|
||||||
|
-- 5 задание
|
||||||
|
with CTE as (
|
||||||
|
select product_id, SUM(quantity * price_at_purchase) as product_revenue
|
||||||
|
from order_items
|
||||||
|
group by product_id
|
||||||
|
)
|
||||||
|
select p.name as product_name, p.category, c.product_revenue from CTE c
|
||||||
|
join products p on c.product_id = p.id
|
||||||
|
order by c.product_revenue desc
|
||||||
|
limit 3;
|
||||||
|
|
||||||
|
-- 6 задание
|
||||||
|
with CTE as (
|
||||||
|
select o.user_id, SUM(quantity * price_at_purchase) as total_revenue from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
group by o.user_id
|
||||||
|
)
|
||||||
|
select u.name, u.email, c.total_revenue from users u
|
||||||
|
join CTE c on u.id = c.user_id
|
||||||
|
where u.is_active is true
|
||||||
|
and c.total_revenue > 10000;
|
||||||
|
|
||||||
|
-- 7 задание
|
||||||
|
|
||||||
|
with CTE as (
|
||||||
|
select order_id, SUM(quantity * price_at_purchase) as order_revenue
|
||||||
|
from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
where o.status = 'paid'
|
||||||
|
group by order_id
|
||||||
|
)
|
||||||
|
select * from CTE
|
||||||
|
where order_revenue < 10000;
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------
|
||||||
|
--WINDOW FUNCTIONS
|
||||||
|
-- 1 задание
|
||||||
|
select u.id as user_id, u.name, o.id as order_id, o.order_date,
|
||||||
|
row_number() over (partition by o.user_id order by o.order_date) as order_number_for_user
|
||||||
|
from users u
|
||||||
|
join orders o on u.id = o.user_id;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
with CTE as (
|
||||||
|
select u.id as user_id, u.name as user_name, order_id, o.order_date, SUM(quantity * price_at_purchase) as order_revenue
|
||||||
|
from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
join users u on o.user_id = u.id
|
||||||
|
group by u.id, u.name, order_id, o.order_date
|
||||||
|
order by user_id
|
||||||
|
)
|
||||||
|
select user_id, user_name, order_id, order_date, order_revenue,
|
||||||
|
SUM(order_revenue) over (partition by user_id order by order_date) as running_revenue_for_user
|
||||||
|
from CTE
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
with CTE as (
|
||||||
|
select u.id as user_id, u.name as user_name, SUM(quantity * price_at_purchase) as total_revenue
|
||||||
|
from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
join users u on o.user_id = u.id
|
||||||
|
group by u.id, u.name
|
||||||
|
)
|
||||||
|
select user_name, total_revenue,
|
||||||
|
RANK() over (order by total_revenue desc) as revenue_rank,
|
||||||
|
dense_rank() over (order by total_revenue desc) as dense_revenue_rank
|
||||||
|
from CTE;
|
||||||
|
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
select u.name, o.id as order_id, order_date,
|
||||||
|
first_value(o.order_date) over (partition by user_id order by order_date) as first_order_date,
|
||||||
|
last_value(o.order_date) over (partition by user_id order by order_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_order_date
|
||||||
|
from orders o
|
||||||
|
join users u on u.id = o.user_id;
|
||||||
|
|
||||||
|
|
||||||
|
-- 5 задание
|
||||||
|
select u.name as user_name, o.id as order_id,
|
||||||
|
COUNT(*) over (partition by u.id) as orders_per_user
|
||||||
|
from users u
|
||||||
|
join orders o on u.id = o.user_id;
|
||||||
|
|
||||||
|
-- 6 задание
|
||||||
|
with CTE as (
|
||||||
|
select u.id as user_id, u.name as user_name, order_id, o.order_date as order_date,
|
||||||
|
SUM(quantity * price_at_purchase) as order_revenue
|
||||||
|
from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
join users u on o.user_id = u.id
|
||||||
|
group by u.id, u.name, order_id, o.order_date
|
||||||
|
order by user_id
|
||||||
|
)
|
||||||
|
select user_name, order_id, order_date, order_revenue,
|
||||||
|
LAG(order_revenue) over (partition by user_id order by order_date) as prev_order_revenue
|
||||||
|
from CTE;
|
||||||
|
|
||||||
|
-- 7 задание
|
||||||
|
with CTEa as (
|
||||||
|
select product_id,
|
||||||
|
o.order_date::date as order_date,
|
||||||
|
SUM(quantity * price_at_purchase) as daily_category_revenue
|
||||||
|
from order_items oi
|
||||||
|
join orders o on oi.order_id = o.id
|
||||||
|
group by product_id, order_date
|
||||||
|
order by oi.product_id
|
||||||
|
),
|
||||||
|
CTEb as (
|
||||||
|
select p.category, order_date, daily_category_revenue
|
||||||
|
from CTEa a
|
||||||
|
join products p on a.product_id = p.id
|
||||||
|
)
|
||||||
|
select category, order_date, daily_category_revenue,
|
||||||
|
SUM(daily_category_revenue) over (partition by category order by order_date) as running_category_revenue
|
||||||
|
from CTEb;
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------------------------------
|
||||||
|
-- VIEW and MATERIALIZED VIEW
|
||||||
|
-- 1 задание
|
||||||
|
create MATERIALIZED view mv_category_revenue
|
||||||
|
as
|
||||||
|
select p.category, SUM(quantity * price_at_purchase) as total_revenue
|
||||||
|
from products p
|
||||||
|
join order_items oi on oi.product_id = p.id
|
||||||
|
join orders o on oi.order_id = o.id and o.status = 'paid'
|
||||||
|
group by p.category
|
||||||
|
order by total_revenue desc
|
||||||
|
;
|
||||||
|
|
||||||
|
-- 2 задание
|
||||||
|
create materialized view
|
||||||
|
as
|
||||||
|
select u.id, u.name, COUNT(o.id) as order_count
|
||||||
|
from users u
|
||||||
|
join orders o on u.id = o.user_id and o.status = 'paid'
|
||||||
|
group by u.id, u.name
|
||||||
|
order by order_count desc
|
||||||
|
;
|
||||||
|
|
||||||
|
-- 3 задание
|
||||||
|
create materialized view mv_daily_revenue
|
||||||
|
as
|
||||||
|
select order_date::date as sales_date, SUM(quantity * price_at_purchase) as daily_revenue from orders o
|
||||||
|
join order_items oi on o.id = oi.order_id
|
||||||
|
where o.status = 'paid'
|
||||||
|
group by sales_date
|
||||||
|
order by sales_date
|
||||||
|
;
|
||||||
|
|
||||||
|
-- 4 задание
|
||||||
|
refresh materialized view mv_daily_revenue;
|
||||||
|
|
||||||
|
-- В 1 случае витрину можно обновлять 1 раз в день в 10:00 или 2 раза в день в 10:00 и в 22:00
|
||||||
|
-- Во 2 случае витрину нужно обновлять несколько раз в день, думаю каждые часа 2-3 то есть в 8 в 10 в 12 и тд.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 175 KiB |
@@ -0,0 +1,72 @@
|
|||||||
|
--Задача 1: Создай таблицу page_views
|
||||||
|
|
||||||
|
CREATE TABLE page_views (
|
||||||
|
user_id UInt64,
|
||||||
|
url String,
|
||||||
|
view_time DateTime
|
||||||
|
)
|
||||||
|
ENGINE = MergeTree()
|
||||||
|
PARTITION BY toYYYYMM(view_time)
|
||||||
|
ORDER BY (user_id, view_time);
|
||||||
|
|
||||||
|
--Задача 2: Создай таблицу users
|
||||||
|
|
||||||
|
CREATE TABLE users (
|
||||||
|
id UInt64,
|
||||||
|
name String,
|
||||||
|
updated_at DateTime
|
||||||
|
)
|
||||||
|
ENGINE = ReplacingMergeTree(updated_at)
|
||||||
|
ORDER BY id;
|
||||||
|
|
||||||
|
-- Задача 3: Создай таблицу region_sales
|
||||||
|
|
||||||
|
CREATE TABLE region_sales (
|
||||||
|
region String,
|
||||||
|
date Date,
|
||||||
|
sales UInt64
|
||||||
|
)
|
||||||
|
ENGINE = SummingMergeTree()
|
||||||
|
PARTITION BY toYYYYMM(date)
|
||||||
|
ORDER BY (region, date);
|
||||||
|
|
||||||
|
--Задача 4.1: Создай таблицу user_metrics
|
||||||
|
|
||||||
|
CREATE TABLE user_metrics (
|
||||||
|
region String,
|
||||||
|
avg_age_state AggregateFunction(avg, UInt8),
|
||||||
|
active_users_state AggregateFunction(uniq, UInt64)
|
||||||
|
)
|
||||||
|
ENGINE = AggregatingMergeTree()
|
||||||
|
ORDER BY region;
|
||||||
|
|
||||||
|
--Задача 4.3: - Вставь данные и Читай их через `avgMerge()` и `uniqMerge()`
|
||||||
|
|
||||||
|
INSERT INTO user_metrics
|
||||||
|
SELECT
|
||||||
|
region,
|
||||||
|
avgState(age) AS avg_age_state,
|
||||||
|
uniqState(toUInt64(user_id)) AS active_users_state
|
||||||
|
FROM
|
||||||
|
(
|
||||||
|
SELECT 'Samara' AS region, 25 AS age, 1 AS user_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'Moscow', 30, 2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'Moscow', 22, 3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'Samara', 22, 4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 'Sochi', 34, 5
|
||||||
|
)
|
||||||
|
GROUP BY region;
|
||||||
|
|
||||||
|
--Задача 4.4: - Читай их через `avgMerge()` и `uniqMerge()`
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
region,
|
||||||
|
avgMerge(avg_age_state),
|
||||||
|
uniqMerge(active_users_state)
|
||||||
|
FROM user_metrics
|
||||||
|
GROUP BY region;
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
--Витрина dm.lesson_popularity_summary
|
||||||
|
CREATE MATERIALIZED VIEW dm.lesson_popularity_summary as
|
||||||
|
select
|
||||||
|
l.lesson_id,
|
||||||
|
l.title as lesson_title,
|
||||||
|
c.course_id,
|
||||||
|
c.title as course_title,
|
||||||
|
COUNT(f.user_id) as total_views,
|
||||||
|
COUNT(DISTINCT f.user_id) as unique_users,
|
||||||
|
MIN(f.viewed_at) as first_view,
|
||||||
|
MAX(f.viewed_at) as last_view
|
||||||
|
FROM core.fact_lesson_views f
|
||||||
|
JOIN core.dim_lesson l
|
||||||
|
ON f.lesson_id = l.lesson_id
|
||||||
|
JOIN core.dim_course c
|
||||||
|
ON l.course_id = c.course_id
|
||||||
|
GROUP BY
|
||||||
|
l.lesson_id,
|
||||||
|
l.title,
|
||||||
|
c.course_id,
|
||||||
|
c.title
|
||||||
|
order by lesson_id;
|
||||||
|
|
||||||
|
select * from dm.lesson_popularity_summary;
|
||||||
|
|
||||||
|
--Удалил лишний индекс
|
||||||
|
DROP INDEX core.idx_fact_views_course_id;
|
||||||
|
|
||||||
|
-- Все индексы для CORE-таблиц
|
||||||
|
SELECT
|
||||||
|
tablename,
|
||||||
|
indexname,
|
||||||
|
indexdef
|
||||||
|
FROM pg_indexes
|
||||||
|
WHERE schemaname = 'core'
|
||||||
|
AND tablename IN (
|
||||||
|
'dim_course',
|
||||||
|
'dim_date',
|
||||||
|
'dim_lesson',
|
||||||
|
'dim_user',
|
||||||
|
'enrollments',
|
||||||
|
'fact_lesson_views'
|
||||||
|
)
|
||||||
|
ORDER by indexname, tablename;
|
||||||
|
|
||||||
|
|
||||||
|
--Витрина dm.inactive_users_summary
|
||||||
|
CREATE MATERIALIZED VIEW dm.inactive_users_summary as
|
||||||
|
select
|
||||||
|
du.user_id,
|
||||||
|
du.name as user_name,
|
||||||
|
du.email,
|
||||||
|
du.age,
|
||||||
|
COUNT(e.course_id) as enrollments_count,
|
||||||
|
du.registration_date
|
||||||
|
from core.dim_user du
|
||||||
|
left join core.enrollments e
|
||||||
|
on du.user_id = e.user_id
|
||||||
|
left join core.fact_lesson_views flv
|
||||||
|
on du.user_id = flv.user_id
|
||||||
|
where flv.user_id is NULL
|
||||||
|
group by
|
||||||
|
du.user_id,
|
||||||
|
du.name,
|
||||||
|
du.email,
|
||||||
|
du.age,
|
||||||
|
du.registration_date
|
||||||
|
order by du.user_id;
|
||||||
|
|
||||||
|
select * from dm.inactive_users_summary;
|
||||||
|
|
||||||
|
--Витрина dm.course_completion_rate
|
||||||
|
CREATE MATERIALIZED VIEW dm.course_completion_rate as
|
||||||
|
select
|
||||||
|
du.user_id,
|
||||||
|
du.name as user_name,
|
||||||
|
dc.course_id,
|
||||||
|
dc.title as course_title,
|
||||||
|
COUNT(DISTINCT dl.lesson_id) AS lessons_in_course,
|
||||||
|
COUNT(DISTINCT flv.lesson_id) AS lessons_viewed,
|
||||||
|
ROUND(COUNT(DISTINCT flv.lesson_id)::numeric / NULLIF(COUNT(DISTINCT dl.lesson_id), 0), 2) AS completion_rate
|
||||||
|
from core.enrollments e
|
||||||
|
left join core.dim_user du
|
||||||
|
on du.user_id = e.user_id
|
||||||
|
left join core.dim_course dc
|
||||||
|
on dc.course_id = e.course_id
|
||||||
|
left join core.dim_lesson dl
|
||||||
|
on dl.course_id = e.course_id
|
||||||
|
left join core.fact_lesson_views flv
|
||||||
|
on flv.user_id = e.user_id
|
||||||
|
and flv.lesson_id = dl.lesson_id
|
||||||
|
group by
|
||||||
|
du.user_id,
|
||||||
|
du.name,
|
||||||
|
dc.course_id,
|
||||||
|
dc.title
|
||||||
|
order by du.user_id;
|
||||||
|
|
||||||
|
select * from dm.course_completion_rate order by user_id;
|
||||||
|
|
||||||
|
--Этап 5. Проверка
|
||||||
|
SELECT * FROM dm.lesson_popularity_summary LIMIT 10;
|
||||||
|
SELECT * FROM dm.inactive_users_summary LIMIT 10;
|
||||||
|
SELECT * FROM dm.course_completion_rate LIMIT 10;
|
||||||
|
--Все витрины отображаются корректно. Скрины: "название витрины".png
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
@@ -0,0 +1,508 @@
|
|||||||
|
--
|
||||||
|
-- PostgreSQL database dump
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Dumped from database version 9.4.26
|
||||||
|
-- Dumped by pg_dump version 17.5
|
||||||
|
|
||||||
|
-- Started on 2026-01-17 22:42:00
|
||||||
|
|
||||||
|
SET statement_timeout = 0;
|
||||||
|
SET lock_timeout = 0;
|
||||||
|
SET idle_in_transaction_session_timeout = 0;
|
||||||
|
SET transaction_timeout = 0;
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
|
SET check_function_bodies = false;
|
||||||
|
SET xmloption = content;
|
||||||
|
SET client_min_messages = warning;
|
||||||
|
SET row_security = off;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 10 (class 2615 OID 25610)
|
||||||
|
-- Name: core; Type: SCHEMA; Schema: -; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SCHEMA core;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA core OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 11 (class 2615 OID 25611)
|
||||||
|
-- Name: dm; Type: SCHEMA; Schema: -; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SCHEMA dm;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA dm OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 9 (class 2615 OID 25609)
|
||||||
|
-- Name: raw; Type: SCHEMA; Schema: -; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SCHEMA raw;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA raw OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
SET default_tablespace = '';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 273 (class 1259 OID 25635)
|
||||||
|
-- Name: dim_course; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_course (
|
||||||
|
course_id integer NOT NULL,
|
||||||
|
title text,
|
||||||
|
category text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_course OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 275 (class 1259 OID 25656)
|
||||||
|
-- Name: dim_date; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_date (
|
||||||
|
date date NOT NULL,
|
||||||
|
year integer,
|
||||||
|
month integer,
|
||||||
|
day integer,
|
||||||
|
weekday text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_date OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 274 (class 1259 OID 25643)
|
||||||
|
-- Name: dim_lesson; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_lesson (
|
||||||
|
lesson_id integer NOT NULL,
|
||||||
|
title text,
|
||||||
|
duration_min integer,
|
||||||
|
course_id integer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_lesson OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 272 (class 1259 OID 25627)
|
||||||
|
-- Name: dim_user; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_user (
|
||||||
|
user_id integer NOT NULL,
|
||||||
|
name text,
|
||||||
|
age integer,
|
||||||
|
email text,
|
||||||
|
registration_date date
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_user OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 276 (class 1259 OID 25872)
|
||||||
|
-- Name: enrollments; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.enrollments (
|
||||||
|
user_id integer,
|
||||||
|
course_id integer,
|
||||||
|
enrolled_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.enrollments OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 277 (class 1259 OID 25885)
|
||||||
|
-- Name: fact_lesson_views; Type: TABLE; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE core.fact_lesson_views (
|
||||||
|
user_id integer,
|
||||||
|
lesson_id integer,
|
||||||
|
course_id integer,
|
||||||
|
viewed_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.fact_lesson_views OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 268 (class 1259 OID 25615)
|
||||||
|
-- Name: courses; Type: TABLE; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE raw.courses (
|
||||||
|
id integer,
|
||||||
|
title character varying(50),
|
||||||
|
category character varying(50),
|
||||||
|
created_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.courses OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 270 (class 1259 OID 25621)
|
||||||
|
-- Name: enrollments; Type: TABLE; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE raw.enrollments (
|
||||||
|
id integer,
|
||||||
|
user_id integer,
|
||||||
|
course_id integer,
|
||||||
|
enrolled_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.enrollments OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 271 (class 1259 OID 25624)
|
||||||
|
-- Name: lesson_views; Type: TABLE; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE raw.lesson_views (
|
||||||
|
id integer,
|
||||||
|
user_id integer,
|
||||||
|
lesson_id integer,
|
||||||
|
viewed_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.lesson_views OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 269 (class 1259 OID 25618)
|
||||||
|
-- Name: lessons; Type: TABLE; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE raw.lessons (
|
||||||
|
id integer,
|
||||||
|
course_id integer,
|
||||||
|
title character varying(50),
|
||||||
|
duration_min integer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.lessons OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 267 (class 1259 OID 25612)
|
||||||
|
-- Name: users; Type: TABLE; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE raw.users (
|
||||||
|
id integer,
|
||||||
|
name character varying(50),
|
||||||
|
age integer,
|
||||||
|
email character varying(50),
|
||||||
|
registration_date character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.users OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2506 (class 0 OID 25635)
|
||||||
|
-- Dependencies: 273
|
||||||
|
-- Data for Name: dim_course; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_course (course_id, title, category) FROM stdin;
|
||||||
|
2 Python для анализа данных programming
|
||||||
|
1 SQL для начинающих data
|
||||||
|
3 BI с нуля business
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2508 (class 0 OID 25656)
|
||||||
|
-- Dependencies: 275
|
||||||
|
-- Data for Name: dim_date; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_date (date, year, month, day, weekday) FROM stdin;
|
||||||
|
2023-01-15 2023 1 15 Sunday
|
||||||
|
2023-01-16 2023 1 16 Monday
|
||||||
|
2023-01-21 2023 1 21 Saturday
|
||||||
|
2023-01-20 2023 1 20 Friday
|
||||||
|
2023-03-05 2023 3 5 Sunday
|
||||||
|
2023-02-01 2023 2 1 Wednesday
|
||||||
|
2023-04-02 2023 4 2 Sunday
|
||||||
|
2023-03-06 2023 3 6 Monday
|
||||||
|
2023-04-01 2023 4 1 Saturday
|
||||||
|
2023-04-03 2023 4 3 Monday
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2507 (class 0 OID 25643)
|
||||||
|
-- Dependencies: 274
|
||||||
|
-- Data for Name: dim_lesson; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_lesson (lesson_id, title, duration_min, course_id) FROM stdin;
|
||||||
|
4 Основы BI 12 3
|
||||||
|
5 Метрики и дашборды 18 3
|
||||||
|
2 JOIN 15 1
|
||||||
|
1 SELECT и FROM 10 1
|
||||||
|
3 Pandas 20 2
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2505 (class 0 OID 25627)
|
||||||
|
-- Dependencies: 272
|
||||||
|
-- Data for Name: dim_user; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_user (user_id, name, age, email, registration_date) FROM stdin;
|
||||||
|
3 Charlie 22 charlie@mail.com 2023-02-20
|
||||||
|
1 Alice 25 alice@mail.com 2023-01-10
|
||||||
|
2 Bob 30 bob@gmail.com 2023-02-05
|
||||||
|
5 Ethan 35 ethan@gmail.com 2023-03-10
|
||||||
|
4 Diana 28 diana@mail.com 2023-03-01
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2509 (class 0 OID 25872)
|
||||||
|
-- Dependencies: 276
|
||||||
|
-- Data for Name: enrollments; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.enrollments (user_id, course_id, enrolled_at) FROM stdin;
|
||||||
|
4 3 2023-04-01 00:00:00
|
||||||
|
1 2 2023-02-01 00:00:00
|
||||||
|
2 1 2023-01-20 00:00:00
|
||||||
|
1 1 2023-01-15 00:00:00
|
||||||
|
3 2 2023-03-05 00:00:00
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2510 (class 0 OID 25885)
|
||||||
|
-- Dependencies: 277
|
||||||
|
-- Data for Name: fact_lesson_views; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.fact_lesson_views (user_id, lesson_id, course_id, viewed_at) FROM stdin;
|
||||||
|
2 1 1 2023-01-21 09:00:00
|
||||||
|
1 2 1 2023-01-16 10:15:00
|
||||||
|
3 3 2 2023-03-06 12:00:00
|
||||||
|
1 1 1 2023-01-16 10:00:00
|
||||||
|
4 4 3 2023-04-02 10:00:00
|
||||||
|
4 5 3 2023-04-03 10:00:00
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2501 (class 0 OID 25615)
|
||||||
|
-- Dependencies: 268
|
||||||
|
-- Data for Name: courses; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.courses (id, title, category, created_at) FROM stdin;
|
||||||
|
3 BI с нуля business 2023-03-01
|
||||||
|
1 SQL для начинающих data 2023-01-01
|
||||||
|
2 Python для анализа данных programming 2023-01-15
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2503 (class 0 OID 25621)
|
||||||
|
-- Dependencies: 270
|
||||||
|
-- Data for Name: enrollments; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.enrollments (id, user_id, course_id, enrolled_at) FROM stdin;
|
||||||
|
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
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2504 (class 0 OID 25624)
|
||||||
|
-- Dependencies: 271
|
||||||
|
-- Data for Name: lesson_views; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.lesson_views (id, user_id, lesson_id, viewed_at) FROM stdin;
|
||||||
|
2 1 2 2023-01-16 10:15:00.000
|
||||||
|
1 1 1 2023-01-16 10:00:00.000
|
||||||
|
3 2 1 2023-01-21 09:00:00.000
|
||||||
|
5 4 4 2023-04-02 10:00:00.000
|
||||||
|
4 3 3 2023-03-06 12:00:00.000
|
||||||
|
6 4 5 2023-04-03 10:00:00.000
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2502 (class 0 OID 25618)
|
||||||
|
-- Dependencies: 269
|
||||||
|
-- Data for Name: lessons; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.lessons (id, course_id, title, duration_min) FROM stdin;
|
||||||
|
1 1 SELECT и FROM 10
|
||||||
|
2 1 JOIN 15
|
||||||
|
3 2 Pandas 20
|
||||||
|
4 3 Основы BI 12
|
||||||
|
5 3 Метрики и дашборды 18
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2500 (class 0 OID 25612)
|
||||||
|
-- Dependencies: 267
|
||||||
|
-- Data for Name: users; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.users (id, name, age, email, registration_date) FROM stdin;
|
||||||
|
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
|
||||||
|
5 Ethan 35 ethan@gmail.com 2023-03-10
|
||||||
|
4 Diana 28 diana@mail.com 2023-03-01
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2314 (class 2606 OID 25642)
|
||||||
|
-- Name: dim_course dim_course_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_course
|
||||||
|
ADD CONSTRAINT dim_course_pkey PRIMARY KEY (course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2319 (class 2606 OID 25663)
|
||||||
|
-- Name: dim_date dim_date_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_date
|
||||||
|
ADD CONSTRAINT dim_date_pkey PRIMARY KEY (date);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2316 (class 2606 OID 25650)
|
||||||
|
-- Name: dim_lesson dim_lesson_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_lesson
|
||||||
|
ADD CONSTRAINT dim_lesson_pkey PRIMARY KEY (lesson_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2312 (class 2606 OID 25634)
|
||||||
|
-- Name: dim_user dim_user_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_user
|
||||||
|
ADD CONSTRAINT dim_user_pkey PRIMARY KEY (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2317 (class 1259 OID 25906)
|
||||||
|
-- Name: idx_dim_lesson_course_id; Type: INDEX; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
1) Создание INDEX на таблицы в CORE-слое
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE INDEX idx_dim_lesson_course_id ON core.dim_lesson USING btree (course_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_enrollments_course_id ON core.enrollments USING btree (course_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_fact_views_course_id ON core.fact_lesson_views USING btree (course_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_fact_views_course_viewed_at ON core.fact_lesson_views USING btree (course_id, viewed_at);
|
||||||
|
|
||||||
|
CREATE INDEX idx_fact_views_lesson_id ON core.fact_lesson_views USING btree (lesson_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_fact_views_user_id ON core.fact_lesson_views USING btree (user_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_fact_views_user_viewed_at ON core.fact_lesson_views USING btree (user_id, viewed_at);
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_lesson
|
||||||
|
ADD CONSTRAINT dim_lesson_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2327 (class 2606 OID 25880)
|
||||||
|
-- Name: enrollments enrollments_course_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.enrollments
|
||||||
|
ADD CONSTRAINT enrollments_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2328 (class 2606 OID 25875)
|
||||||
|
-- Name: enrollments enrollments_user_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.enrollments
|
||||||
|
ADD CONSTRAINT enrollments_user_id_fkey FOREIGN KEY (user_id) REFERENCES core.dim_user(user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2329 (class 2606 OID 25898)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_course_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2330 (class 2606 OID 25893)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_lesson_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_lesson_id_fkey FOREIGN KEY (lesson_id) REFERENCES core.dim_lesson(lesson_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2331 (class 2606 OID 25888)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_user_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_user_id_fkey FOREIGN KEY (user_id) REFERENCES core.dim_user(user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- Completed on 2026-01-17 22:42:02
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PostgreSQL database dump complete
|
||||||
|
--
|
||||||
|
|
||||||
@@ -0,0 +1,417 @@
|
|||||||
|
SET statement_timeout = 0;
|
||||||
|
SET lock_timeout = 0;
|
||||||
|
SET idle_in_transaction_session_timeout = 0;
|
||||||
|
SET transaction_timeout = 0;
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
|
SET check_function_bodies = false;
|
||||||
|
SET xmloption = content;
|
||||||
|
SET client_min_messages = warning;
|
||||||
|
SET row_security = off;
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- ЭТАП 1
|
||||||
|
-- 1.1 - СОЗДАНИЕ СХЕМ
|
||||||
|
|
||||||
|
CREATE SCHEMA core;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA core OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE SCHEMA dm;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA dm OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE SCHEMA raw;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER SCHEMA raw OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
SET default_tablespace = '';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 1.2 - Создание raw-таблиц
|
||||||
|
|
||||||
|
CREATE TABLE raw.courses (
|
||||||
|
id integer,
|
||||||
|
title character varying(50),
|
||||||
|
category character varying(50),
|
||||||
|
created_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.courses OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE raw.enrollments (
|
||||||
|
id integer,
|
||||||
|
user_id integer,
|
||||||
|
course_id integer,
|
||||||
|
enrolled_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.enrollments OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE raw.lesson_views (
|
||||||
|
id integer,
|
||||||
|
user_id integer,
|
||||||
|
lesson_id integer,
|
||||||
|
viewed_at character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.lesson_views OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE raw.lessons (
|
||||||
|
id integer,
|
||||||
|
course_id integer,
|
||||||
|
title character varying(50),
|
||||||
|
duration_min integer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.lessons OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE raw.users (
|
||||||
|
id integer,
|
||||||
|
name character varying(50),
|
||||||
|
age integer,
|
||||||
|
email character varying(50),
|
||||||
|
registration_date character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE raw.users OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Этап 3. Слой Core
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_course (
|
||||||
|
course_id integer NOT NULL,
|
||||||
|
title text,
|
||||||
|
category text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_course OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_date (
|
||||||
|
date date NOT NULL,
|
||||||
|
year integer,
|
||||||
|
month integer,
|
||||||
|
day integer,
|
||||||
|
weekday text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_date OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_lesson (
|
||||||
|
lesson_id integer NOT NULL,
|
||||||
|
title text,
|
||||||
|
duration_min integer,
|
||||||
|
course_id integer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_lesson OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE core.dim_user (
|
||||||
|
user_id integer NOT NULL,
|
||||||
|
name text,
|
||||||
|
age integer,
|
||||||
|
email text,
|
||||||
|
registration_date date
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.dim_user OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE core.enrollments (
|
||||||
|
user_id integer,
|
||||||
|
course_id integer,
|
||||||
|
enrolled_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.enrollments OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE core.fact_lesson_views (
|
||||||
|
user_id integer,
|
||||||
|
lesson_id integer,
|
||||||
|
course_id integer,
|
||||||
|
viewed_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE core.fact_lesson_views OWNER TO dsolovianov;
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
COPY core.dim_course (course_id, title, category) FROM stdin;
|
||||||
|
2 Python для анализа данных programming
|
||||||
|
1 SQL для начинающих data
|
||||||
|
3 BI с нуля business
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
COPY core.dim_date (date, year, month, day, weekday) FROM stdin;
|
||||||
|
2023-01-15 2023 1 15 Sunday
|
||||||
|
2023-01-16 2023 1 16 Monday
|
||||||
|
2023-01-21 2023 1 21 Saturday
|
||||||
|
2023-01-20 2023 1 20 Friday
|
||||||
|
2023-03-05 2023 3 5 Sunday
|
||||||
|
2023-02-01 2023 2 1 Wednesday
|
||||||
|
2023-04-02 2023 4 2 Sunday
|
||||||
|
2023-03-06 2023 3 6 Monday
|
||||||
|
2023-04-01 2023 4 1 Saturday
|
||||||
|
2023-04-03 2023 4 3 Monday
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2500 (class 0 OID 25643)
|
||||||
|
-- Dependencies: 274
|
||||||
|
-- Data for Name: dim_lesson; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_lesson (lesson_id, title, duration_min, course_id) FROM stdin;
|
||||||
|
4 Основы BI 12 3
|
||||||
|
5 Метрики и дашборды 18 3
|
||||||
|
2 JOIN 15 1
|
||||||
|
1 SELECT и FROM 10 1
|
||||||
|
3 Pandas 20 2
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2498 (class 0 OID 25627)
|
||||||
|
-- Dependencies: 272
|
||||||
|
-- Data for Name: dim_user; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.dim_user (user_id, name, age, email, registration_date) FROM stdin;
|
||||||
|
3 Charlie 22 charlie@mail.com 2023-02-20
|
||||||
|
1 Alice 25 alice@mail.com 2023-01-10
|
||||||
|
2 Bob 30 bob@gmail.com 2023-02-05
|
||||||
|
5 Ethan 35 ethan@gmail.com 2023-03-10
|
||||||
|
4 Diana 28 diana@mail.com 2023-03-01
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2502 (class 0 OID 25872)
|
||||||
|
-- Dependencies: 276
|
||||||
|
-- Data for Name: enrollments; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.enrollments (user_id, course_id, enrolled_at) FROM stdin;
|
||||||
|
4 3 2023-04-01 00:00:00
|
||||||
|
1 2 2023-02-01 00:00:00
|
||||||
|
2 1 2023-01-20 00:00:00
|
||||||
|
1 1 2023-01-15 00:00:00
|
||||||
|
3 2 2023-03-05 00:00:00
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2503 (class 0 OID 25885)
|
||||||
|
-- Dependencies: 277
|
||||||
|
-- Data for Name: fact_lesson_views; Type: TABLE DATA; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY core.fact_lesson_views (user_id, lesson_id, course_id, viewed_at) FROM stdin;
|
||||||
|
2 1 1 2023-01-21 09:00:00
|
||||||
|
1 2 1 2023-01-16 10:15:00
|
||||||
|
3 3 2 2023-03-06 12:00:00
|
||||||
|
1 1 1 2023-01-16 10:00:00
|
||||||
|
4 4 3 2023-04-02 10:00:00
|
||||||
|
4 5 3 2023-04-03 10:00:00
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2494 (class 0 OID 25615)
|
||||||
|
-- Dependencies: 268
|
||||||
|
-- Data for Name: courses; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.courses (id, title, category, created_at) FROM stdin;
|
||||||
|
3 BI с нуля business 2023-03-01
|
||||||
|
1 SQL для начинающих data 2023-01-01
|
||||||
|
2 Python для анализа данных programming 2023-01-15
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2496 (class 0 OID 25621)
|
||||||
|
-- Dependencies: 270
|
||||||
|
-- Data for Name: enrollments; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.enrollments (id, user_id, course_id, enrolled_at) FROM stdin;
|
||||||
|
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
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2497 (class 0 OID 25624)
|
||||||
|
-- Dependencies: 271
|
||||||
|
-- Data for Name: lesson_views; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.lesson_views (id, user_id, lesson_id, viewed_at) FROM stdin;
|
||||||
|
2 1 2 2023-01-16 10:15:00.000
|
||||||
|
1 1 1 2023-01-16 10:00:00.000
|
||||||
|
3 2 1 2023-01-21 09:00:00.000
|
||||||
|
5 4 4 2023-04-02 10:00:00.000
|
||||||
|
4 3 3 2023-03-06 12:00:00.000
|
||||||
|
6 4 5 2023-04-03 10:00:00.000
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2495 (class 0 OID 25618)
|
||||||
|
-- Dependencies: 269
|
||||||
|
-- Data for Name: lessons; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.lessons (id, course_id, title, duration_min) FROM stdin;
|
||||||
|
1 1 SELECT и FROM 10
|
||||||
|
2 1 JOIN 15
|
||||||
|
3 2 Pandas 20
|
||||||
|
4 3 Основы BI 12
|
||||||
|
5 3 Метрики и дашборды 18
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2493 (class 0 OID 25612)
|
||||||
|
-- Dependencies: 267
|
||||||
|
-- Data for Name: users; Type: TABLE DATA; Schema: raw; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY raw.users (id, name, age, email, registration_date) FROM stdin;
|
||||||
|
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
|
||||||
|
5 Ethan 35 ethan@gmail.com 2023-03-10
|
||||||
|
4 Diana 28 diana@mail.com 2023-03-01
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2314 (class 2606 OID 25642)
|
||||||
|
-- Name: dim_course dim_course_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_course
|
||||||
|
ADD CONSTRAINT dim_course_pkey PRIMARY KEY (course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2318 (class 2606 OID 25663)
|
||||||
|
-- Name: dim_date dim_date_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_date
|
||||||
|
ADD CONSTRAINT dim_date_pkey PRIMARY KEY (date);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2316 (class 2606 OID 25650)
|
||||||
|
-- Name: dim_lesson dim_lesson_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_lesson
|
||||||
|
ADD CONSTRAINT dim_lesson_pkey PRIMARY KEY (lesson_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2312 (class 2606 OID 25634)
|
||||||
|
-- Name: dim_user dim_user_pkey; Type: CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_user
|
||||||
|
ADD CONSTRAINT dim_user_pkey PRIMARY KEY (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2319 (class 2606 OID 25651)
|
||||||
|
-- Name: dim_lesson dim_lesson_course_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.dim_lesson
|
||||||
|
ADD CONSTRAINT dim_lesson_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2320 (class 2606 OID 25880)
|
||||||
|
-- Name: enrollments enrollments_course_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.enrollments
|
||||||
|
ADD CONSTRAINT enrollments_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2321 (class 2606 OID 25875)
|
||||||
|
-- Name: enrollments enrollments_user_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.enrollments
|
||||||
|
ADD CONSTRAINT enrollments_user_id_fkey FOREIGN KEY (user_id) REFERENCES core.dim_user(user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2322 (class 2606 OID 25898)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_course_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_course_id_fkey FOREIGN KEY (course_id) REFERENCES core.dim_course(course_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2323 (class 2606 OID 25893)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_lesson_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_lesson_id_fkey FOREIGN KEY (lesson_id) REFERENCES core.dim_lesson(lesson_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TOC entry 2324 (class 2606 OID 25888)
|
||||||
|
-- Name: fact_lesson_views fact_lesson_views_user_id_fkey; Type: FK CONSTRAINT; Schema: core; Owner: dsolovianov
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY core.fact_lesson_views
|
||||||
|
ADD CONSTRAINT fact_lesson_views_user_id_fkey FOREIGN KEY (user_id) REFERENCES core.dim_user(user_id);
|
||||||
|
|
||||||
|
|
||||||
|
-- Completed on 2026-01-14 21:29:24
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PostgreSQL database dump complete
|
||||||
|
--
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
"id","title","category","created_at"
|
||||||
|
1,SQL для начинающих,data,2023-01-01
|
||||||
|
2,Python для анализа данных,programming,2023-01-15
|
||||||
|
3,BI с нуля,business,2023-03-01
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
"id","user_id","course_id","enrolled_at"
|
||||||
|
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
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
"id","user_id","lesson_id","viewed_at"
|
||||||
|
1,1,1,2023-01-16 10:00:00.000
|
||||||
|
2,1,2,2023-01-16 10:15:00.000
|
||||||
|
3,2,1,2023-01-21 09:00:00.000
|
||||||
|
4,3,3,2023-03-06 12:00:00.000
|
||||||
|
5,4,4,2023-04-02 10:00:00.000
|
||||||
|
6,4,5,2023-04-03 10:00:00.000
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
"id","course_id","title","duration_min"
|
||||||
|
1,1,SELECT и FROM,10
|
||||||
|
2,1,JOIN,15
|
||||||
|
3,2,Pandas,20
|
||||||
|
4,3,Основы BI,12
|
||||||
|
5,3,Метрики и дашборды,18
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
"id","name","age","email","registration_date"
|
||||||
|
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
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
select * from users;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
select * from users;
|
||||||
Reference in New Issue
Block a user