Files
homework/dmedvedev/4.5.greenplum_pet_project.sql
T
2026-07-30 00:37:12 +05:00

261 lines
10 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--Добавление raw-таблиц в GREENPLUM
CREATE TABLE raw.pet_users
(
id INT PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL,
age INT,
email VARCHAR(100) NOT NULL,
registration_date DATE NOT NULL
);
CREATE TABLE raw.pet_courses
(
id INT PRIMARY KEY NOT NULL,
title VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
created_at DATE NOT NULL
);
CREATE TABLE raw.pet_lessons
(
id INT PRIMARY KEY NOT NULL,
course_id INT NOT NULL,
FOREIGN KEY (course_id) REFERENCES raw.pet_courses (id),
title VARCHAR(50),
duration_min INT NOT NULL
);
CREATE TABLE raw.pet_enrollments
(
id INT PRIMARY KEY NOT NULL,
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES raw.pet_users (id),
course_id INT NOT NULL,
FOREIGN KEY (course_id) REFERENCES raw.pet_courses (id),
enrolled_at DATE NOT NULL
);
CREATE TABLE raw.pet_lesson_views
(
id INT PRIMARY KEY NOT NULL,
user_id INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES raw.pet_users (id),
lesson_id INT NOT NULL,
FOREIGN KEY(lesson_id) REFERENCES raw.pet_lessons (id),
viewed_at TIMESTAMPTZ NOT NULL
);
--Создание core-таблиц (измерений - dimension) в GREENPLUM
-- Измерение пользователей
CREATE TABLE core.dim_user
(
user_id INT PRIMARY KEY,
name TEXT,
age INT,
email TEXT,
registration_date DATE
);
-- Измерение курсов
CREATE TABLE core.dim_course
(
course_id INT PRIMARY KEY,
title TEXT,
category TEXT
);
-- Измерение уроков
CREATE TABLE core.dim_lesson
(
lesson_id INT PRIMARY KEY,
title TEXT,
duration_min INT,
course_id INT REFERENCES core.dim_course(course_id)
);
-- Опционально: измерение времени
CREATE TABLE core.dim_date
(
date DATE PRIMARY KEY,
year INT,
month INT,
day INT,
weekday TEXT
);
--Создание core-таблиц (факты - fact table) в GREENPLUM
CREATE TABLE core.fact_lesson_views
(
user_id INT REFERENCES core.dim_user(user_id),
lesson_id INT REFERENCES core.dim_lesson(lesson_id),
course_id INT REFERENCES core.dim_course(course_id),
viewed_at TIMESTAMP
);
CREATE TABLE core.enrollments
(
user_id INT REFERENCES core.dim_user(user_id),
course_id INT REFERENCES core.dim_course(course_id),
enrolled_at TIMESTAMP
);
--ETL переброска данных из raw в core в GREENPLUM
--переброска для dim_user
INSERT INTO core.dim_user
(user_id, name, age, email, registration_date)
SELECT DISTINCT
user_id::INT,
name::TEXT,
age::INT,
email::TEXT,
registration_date::DATE
FROM raw.users;
--переброска для dim_course
INSERT INTO core.dim_course
(course_id, title, category)
SELECT DISTINCT
id::INT,
title::VARCHAR(100),
category::VARCHAR(50)
FROM raw.pet_courses;
--переброска для dim_lesson
INSERT INTO core.dim_lesson
(lesson_id, title, duration_min, course_id)
SELECT DISTINCT
id::INT,
title::VARCHAR(50),
duration_min::INT,
course_id::INT
FROM raw.pet_lessons;
--переброска для dim_date
--ЗДЕСЬ Я ВЫБРАЛ ПОДТЯГИВАНИЕ ДАТ ИЗ ТАБЛИЦЫ ПРОСМОТРОВ УРОКОВ
INSERT INTO core.dim_date
(date, YEAR, MONTH, DAY, weekday)
SELECT DISTINCT
viewed_at::date,
EXTRACT(YEAR FROM viewed_at),
EXTRACT(MONTH FROM viewed_at),
EXTRACT(DAY FROM viewed_at),
EXTRACT(ISODOW FROM viewed_at)
FROM raw.pet_lesson_views;
--переброска для enrollments
INSERT INTO core.enrollments
(user_id, course_id, enrolled_at)
SELECT
user_id::INT,
course_id::INT,
enrolled_at::DATE
FROM raw.pet_enrollments;
--переброска для fact_lesson_views
--ЗДЕСЬ ПО ИДЕЕ ДОЛЖЕН БЫЛ ПОДТЯНУТЬ АЙДИШНИК КУРСА, НО ЕГО НЕТ В ИСХОДНОЙ ТАБЛИЦЕ raw.pet_lesson_views, ПРАВИЛЬНО ЛИ Я СДЕЛАЛ, ЧТО ПРОСТО НЕ ДОБАВИЛ ЕГО В ЗАПРОС??????
INSERT INTO core.fact_lesson_views
(user_id, lesson_id, viewed_at)
SELECT
user_id::INT,
lesson_id::INT,
viewed_at::TIMESTAMPTZ
FROM raw.pet_lesson_views;
--ВИТРИНА dm.lesson_popularity_summary
CREATE MATERIALIZED VIEW dm.lesson_popularity_summary AS
SELECT
flv.lesson_id AS lesson_id,
dl.title AS lesson_title,
dc.course_id AS course_id,
dc.title AS course_title,
COUNT(*) AS total_views,
COUNT(DISTINCT user_id) AS unique_users,
MIN(viewed_at) AS first_view,
MAX(viewed_at) AS last_view
FROM core.fact_lesson_views flv
LEFT JOIN core.dim_lesson dl ON flv.lesson_id = dl.lesson_id
LEFT JOIN core.dim_course dc ON dl.course_id = dc.course_id
GROUP BY flv.lesson_id, dl.title, dc.course_id, dc.title
ORDER BY lesson_id;
--ВИТРИНА dm.inactive_users_summary
CREATE MATERIALIZED VIEW dm.inactive_users_summary AS
SELECT
du.user_id AS user_id,
du.name AS user_name,
du.email,
du.age,
COUNT(DISTINCT 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;
--ВИТРИНА dm.course_completion_rate
CREATE MATERIALIZED VIEW dm.course_completion_rate AS
SELECT
du.user_id AS user_id,
du.name AS user_name,
e.course_id AS course_id,
(
SELECT
dc.title
FROM core.dim_course dc
WHERE e.course_id = dc.course_id
) 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) * 1.0 / NULLIF(COUNT(dl.lesson_id), 0), 2) AS completion_rate
FROM core.dim_user du
LEFT JOIN core.enrollments e ON du.user_id = e.user_id
LEFT JOIN core.dim_lesson dl ON e.course_id = dl.course_id
LEFT JOIN core.fact_lesson_views flv ON dl.lesson_id = flv.lesson_id AND du.user_id = flv.user_id
GROUP BY du.user_id, du.name, e.course_id, course_title;
--✅ Задание 10: Проверь витрины
ДАННЫЕ ВЫВОДЯТСЯ, ОНИ КОРРЕКТНЫ
SELECT * FROM dm.lesson_popularity_summary LIMIT 10;
SELECT * FROM dm.lesson_popularity_summary LIMIT 10;
lesson_id lesson_title course_id course_title total_views unique_users first_view last_view
2 JOIN 1 SQL для начинающих 6 6 2023-01-07 10:15:00.000 2023-02-26 11:20:00.000
3 WHERE и фильтрация 1 SQL для начинающих 5 5 2023-01-08 09:00:00.000 2023-04-10 11:30:00.000
6 Pandas основы 2 Python для анализа данных 6 6 2023-01-10 14:00:00.000 2023-03-12 14:00:00.000
7 NumPy 2 Python для анализа данных 4 4 2023-01-11 10:00:00.000 2023-03-13 09:00:00.000
9 Основы BI 3 BI с нуля 6 6 2023-01-10 08:00:00.000 2023-04-02 10:00:00.000
14 Графики и диаграммы 4 Excel для аналитиков 1 1 2023-02-07 10:00:00.000 2023-02-07 10:00:00.000
15 Введение в ML 5 Основы машинного обучения 1 1 2023-03-21 10:00:00.000 2023-03-21 10:00:00.000
16 Линейная регрессия 5 Основы машинного обучения 1 1 2023-03-22 11:00:00.000 2023-03-22 11:00:00.000
1 SELECT и FROM 1 SQL для начинающих 9 8 2023-01-07 10:00:00.000 2023-04-10 11:00:00.000
4 Агрегации и GROUP BY 1 SQL для начинающих 5 3 2023-01-08 09:30:00.000 2023-01-18 10:00:00.000
SELECT * FROM dm.inactive_users_summary LIMIT 10;
user_id user_name email age enrollments_count registration_date
8 Henry henry@mail.com 32 3 2023-01-20
16 Paul paul@mail.com 29 2 2023-02-15
18 Rita rita@mail.com 27 2 2023-04-01
17 Quinn quinn@gmail.com 24 2 2023-03-20
20 Tina tina@mail.com 25 1 2023-04-18
10 Jack jack@mail.com 27 1 2023-04-15
19 Sam sam@gmail.com 30 2 2023-04-10
11 Kelly kelly@gmail.com 23 1 2023-04-20
15 Oscar oscar@gmail.com 33 3 2023-01-10
SELECT * FROM dm.course_completion_rate LIMIT 10;
user_id user_name course_id course_title lessons_is_course lesson_viewed completion_rate
2 Bob 1 SQL для начинающих 5 1 0.20
2 Bob 3 BI с нуля 3 2 0.67
3 Charlie 1 SQL для начинающих 5 2 0.40
3 Charlie 2 Python для анализа данных 3 1 0.33
4 Diana 2 Python для анализа данных 3 2 0.67
4 Diana 3 BI с нуля 3 2 0.67
6 Frank 1 SQL для начинающих 5 5 1.00
6 Frank 2 Python для анализа данных 3 3 1.00
6 Frank 3 BI с нуля 3 1 0.33
6 Frank 4 Excel для аналитиков 3 3 1.00