Files
homework/amaksatov/postgresql/OS-330.sql
T
2026-01-11 18:47:48 +06:00

69 lines
2.5 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.
CREATE MATERIALIZED VIEW user_activity_summary AS
SELECT
u.id AS user_id, -- user_id
u.name, -- name
COUNT(DISTINCT e.course_id) AS enrollment_count, -- кол-во записей на курсы
COUNT(DISTINCT lv.lesson_id) AS viewed_lessons_count, -- кол-во просмотренных уроков
MAX(lv.viewed_at) AS last_viewed, -- последний просмотр
MIN(lv.viewed_at) AS first_viewed, -- первый просмотр
ROUND(COUNT(DISTINCT l.course_id) * 100.0 / COUNT(DISTINCT l.id), 2) || '%' AS engagement_rate -- вовлеченность(процент просмотренных/записанным)
FROM amaksatov.users u -- основная таблица
JOIN enrollments e ON e.user_id = u.id -- связь users с enrollments
LEFT JOIN lesson_views lv ON lv.user_id = e.user_id -- связь lessons с lesson_views
JOIN lessons l ON l.course_id = e.course_id -- связь уроков с курсами пользователя
GROUP BY u.id, u.name -- группировка по user_id и name
ORDER BY user_id; -- сортировка по user_id
CREATE MATERIALIZED VIEW course_summary 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,
COUNT(DISTINCT lv.id) AS total_views,
ROUND(
CASE
WHEN COUNT(DISTINCT e.user_id) = 0 THEN NULL
ELSE COUNT(DISTINCT lv.id) * 1.0 / COUNT(DISTINCT e.user_id)
END, 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
LEFT JOIN enrollments e ON e.course_id = c.id
LEFT JOIN lessons l ON c.id = l.course_id
LEFT JOIN lesson_views lv ON lv.lesson_id = l.id
GROUP BY c.id;
CREATE MATERIALIZED VIEW platform_summary AS
WITH
user_stats AS (
SELECT COUNT(*) AS total_users FROM users
),
course_stats AS (
SELECT COUNT(*) AS total_courses FROM courses
),
lesson_stats AS (
SELECT COUNT(*) AS total_lessons FROM lessons
),
view_stats AS (
SELECT COUNT(*) AS total_views, COUNT(DISTINCT user_id) AS users_with_views
FROM lesson_views
)
SELECT
u.total_users,
c.total_courses,
l.total_lessons,
v.users_with_views,
ROUND(l.total_lessons::decimal / NULLIF(c.total_courses, 0), 2) AS avg_lessons_per_course,
ROUND(v.total_views::decimal / NULLIF(l.total_lessons, 0), 2) AS avg_views_per_lesson
FROM user_stats u, course_stats c, lesson_stats l, view_stats v;