diff --git a/bhabibullin/greenplum/pet_project_gp.sql b/bhabibullin/greenplum/pet_project_gp.sql new file mode 100644 index 0000000..3481821 --- /dev/null +++ b/bhabibullin/greenplum/pet_project_gp.sql @@ -0,0 +1,180 @@ +CREATE SCHEMA raw; +CREATE SCHEMA core; +CREATE SCHEMA dm; + +CREATE TABLE raw.users ( + id INT, + name VARCHAR(255), + age INT, + email VARCHAR(255), + registration_date DATE +); + +CREATE TABLE raw.courses ( + id INT, + title VARCHAR(255), + category VARCHAR(255), + created_at DATE +); + +CREATE TABLE raw.lessons ( + id INT, + course_id INT, + title VARCHAR(255), + duration_min INT +); + +CREATE TABLE raw.enrollments ( + id INT, + user_id INT, + course_id INT, + enrolled_at DATE +); + +CREATE TABLE raw.lesson_views ( + id INT, + user_id INT, + lesson_id INT, + viewed_at TIMESTAMP +); + +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.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 +); + +INSERT INTO core.dim_user (user_id, name, age, email, registration_date) +SELECT DISTINCT + id::INT, + name::TEXT, + age::INT, + email::TEXT, + registration_date::DATE +FROM raw.users; + +INSERT INTO core.dim_course (course_id, title, category) +SELECT DISTINCT + id::INT, + title::TEXT, + category::TEXT +FROM raw.courses; + +INSERT INTO core.dim_lesson (lesson_id, title, duration_min, course_id) +SELECT DISTINCT + id::INT, + title::TEXT, + duration_min::INT, + course_id::INT +FROM raw.lessons; + +INSERT INTO core.fact_lesson_views (user_id, lesson_id, course_id, viewed_at) +SELECT DISTINCT + rw.user_id::INT, + rw.lesson_id::INT, + l.course_id::INT, + rw.viewed_at::TIMESTAMP +FROM raw.lesson_views rw +JOIN raw.lessons l ON rw.lesson_id = l.id; + + +INSERT INTO core.enrollments (user_id, course_id, enrolled_at) +SELECT DISTINCT + user_id::INT, + course_id::INT, + enrolled_at::DATE +FROM raw.enrollments; + +UPDATE core.enrollments e +SET enrolled_at = lv.viewed_at +FROM raw.lesson_views lv +WHERE lv.user_id = e.user_id; + +ALTER TABLE core.enrollments +ALTER COLUMN enrolled_at TYPE TIMESTAMP; + +CREATE MATERIALIZED VIEW dm.dm_lesson_popularity_summary AS +SELECT + dl.lesson_id, + dl.title AS lesson_title, + dc.course_id, + dc.title AS course_title, + COUNT(flv.lesson_id) AS total_views, + COUNT(DISTINCT du.user_id) AS unique_users, + MIN(flv.viewed_at) AS first_view, + MAX(flv.viewed_at) AS last_view +FROM core.dim_lesson dl +JOIN core.dim_course dc ON dc.course_id = dl.course_id +JOIN core.fact_lesson_views flv ON flv.lesson_id = dl.lesson_id +JOIN core.dim_user du ON du.user_id = flv.user_id +GROUP BY dl.lesson_id, dl.title, dc.course_id, dc.title +ORDER BY dl.lesson_id; + +select * from dm.dm_lesson_popularity_summary +order by lesson_id; + +CREATE MATERIALIZED VIEW dm.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 e.user_id = du.user_id +LEFT JOIN core.fact_lesson_views flv ON flv.user_id = du.user_id +WHERE flv.user_id IS NULL +GROUP BY du.user_id, du.name, du.email, du.age, du.registration_date; + + +CREATE MATERIALIZED VIEW dm.course_completion_rate AS +SELECT + du.user_id, + du.name AS user_name, + c.course_id, + c.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) * 1.0 / + NULLIF(COUNT(DISTINCT dl.lesson_id), 0), + 2 + ) AS completion_rate +FROM core.dim_user du +JOIN core.enrollments e ON du.user_id = e.user_id +JOIN core.dim_course c ON e.course_id = c.course_id +JOIN core.dim_lesson dl ON c.course_id = dl.course_id +LEFT JOIN core.fact_lesson_views flv ON dl.lesson_id = flv.lesson_id + AND flv.user_id = du.user_id +GROUP BY du.user_id, du.name, c.course_id, c.title +ORDER BY du.user_id, c.course_id; + diff --git a/bhabibullin/postgre/postrge_pet_project.sql b/bhabibullin/postgre/postrge_pet_project.sql new file mode 100644 index 0000000..2a7fda1 --- /dev/null +++ b/bhabibullin/postgre/postrge_pet_project.sql @@ -0,0 +1,143 @@ +create table users( + id int primary key, + name varchar(255), + age int, + email varchar(255), + 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'); + +create table courses( + id int primary key, + title varchar(255), + category varchar(255), + 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'); + +create table lessons( + id int primary key, + course_id int, + title varchar(255), + 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, 2, 'Pandas', 20), +(4, 3, 'Основы BI', 12), +(5, 3, 'Метрики и дашборды', 18); + +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'); + +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, 2, 1, '2023-01-21 09:00:00'), +(4, 3, 3, '2023-03-06 12:00:00'), +(5, 4, 4, '2023-04-02 10:00:00'), +(6, 4, 5, '2023-04-03 10:00:00'); + + +create materialized view user_activity_summary as ( +with available_lessons as ( + select + e.user_id, + count(distinct l.id) as cnt_lesson + from lessons l + join enrollments e on e.course_id = l.course_id + group by e.user_id +) +select + u.id, + u.name, + count(distinct e.course_id) as enrrollment_count, + count(distinct lv.lesson_id) as viewed_lessons_count, + max(lv.viewed_at) as last_view, + min(lv.viewed_at) as first_view, + round( + count(distinct lv.lesson_id) * 100.0 / al.cnt_lesson + ,2) || '%' as engagegement_rate +from users u +join enrollments e on u.id = e.user_id +join lesson_views lv on lv.user_id = u.id +join available_lessons al on al.user_id = u.id +group by u.id, u.name, al.cnt_lesson +); + +create materialized view course_summary as( +with view_cnt as ( + select l.course_id, + count(lv.lesson_id) cnt + from lessons l + join lesson_views lv on l.id = lv.lesson_id + group by l.course_id +) +select + c.id as course_id, + c.title, + count(distinct e.user_id) unique_users, + count(distinct l.id) lessons_count, + vc.cnt total_views, + round(vc.cnt * 1.0 / count(distinct e.user_id), 2) as avg_views_per_user, + min(lv.viewed_at) as first_viewed_at, + max(lv.viewed_at) as last_viewed_at +from + courses c + join lessons l on c.id = l.course_id + join enrollments e on e.course_id = c.id + join view_cnt vc on vc.course_id = c.id + join lesson_views lv on lv.lesson_id = l.id +group by c.title, vc.cnt, c.id +order by course_id +); + +create materialized view platform_summary as ( +select + count(distinct u.id) as total_users, + count(distinct c.id) as total_courses, + count(distinct l.id) as total_lessons, + count(distinct lv.user_id) as users_with_views, + round(count(distinct l.id) * 1.0 / count(distinct c.id), 2) as avg_lessons_per_course, + count(lv.lesson_id) * 1.0 / count(distinct l.id) as avg_lessons_per_lesson +from users u +left join lesson_views lv on lv.user_id = u.id +left join lessons l on l.id = lv.lesson_id +left join courses c on c.id = l.course_id +); +