Финальный проект — SQL-дашборд менеджера социальной сети

Применяем весь курс на практике: от простых SELECT до оконных функций и CTE

Прогресс курса Финальный проект

Задача

00

Схема базы данных

Таблицы социальной сети

ТаблицаКлючевые поляОписание
usersid, name, age, gender, cityПользователи
communitiesid, name, ratingСообщества
postsid, community_id, title, scoreПубликации
likesid, user_id, post_id, liked_atЛайки к постам
viewsid, user_id, community_id, viewed_atПросмотры сообществ
01

Общие метрики активности

Первый блок дашборда — сводные цифры: сколько пользователей, лайков, просмотров и каков средний score постов.

SELECT
    (SELECT COUNT(*) FROM users)         AS total_users,
    (SELECT COUNT(*) FROM communities)    AS total_communities,
    (SELECT COUNT(*) FROM posts)          AS total_posts,
    (SELECT COUNT(*) FROM likes)          AS total_likes,
    (SELECT COUNT(*) FROM views)          AS total_views,
    (SELECT ROUND(AVG(score), 1) FROM posts) AS avg_score;
Результат
total_userstotal_communitiestotal_poststotal_likestotal_viewsavg_score
106131818853.8
02

Топ-5 постов по количеству лайков

Какие публикации вызвали наибольший отклик аудитории? Объединяем posts и likes.

SELECT
    p.title,
    c.name              AS community,
    p.score,
    COUNT(l.id)         AS likes_count
FROM   posts p
JOIN   communities c ON c.id = p.community_id
LEFT JOIN likes l    ON l.post_id = p.id
GROUP BY p.id, p.title, c.name, p.score
ORDER BY likes_count DESC, p.score DESC
LIMIT 5;
Результат
titlecommunityscorelikes_count
review top games 2026GamersHub9503
guide photo editing basicsPhotoWorld7803
tutorial Python basicsTechTalks6002
review AI tools for devsTechTalks11002
analysis esports statsGamersHub8702
03

Топ-5 пользователей по активности

Самые активные пользователи — те, кто поставил больше всего лайков. Считаем и добавляем их город.

SELECT
    u.name,
    u.city,
    COUNT(l.id)  AS likes_count
FROM   users u
LEFT JOIN likes l ON l.user_id = u.id
GROUP BY u.id, u.name, u.city
ORDER BY likes_count DESC
LIMIT 5;
Результат
namecitylikes_count
AndreyMoscow4
AnnaSaint Petersburg3
KateNovosibirsk3
NatalieNovosibirsk2
DmitriyMoscow2
04

Метрики по сообществам

Для каждого сообщества: рейтинг, количество постов, средний score постов, количество лайков и просмотров.

SELECT
    c.name,
    c.rating,
    COUNT(DISTINCT p.id)   AS posts_count,
    ROUND(AVG(p.score), 1) AS avg_score,
    COUNT(DISTINCT l.id)   AS likes_count,
    COUNT(DISTINCT v.id)   AS views_count
FROM      communities c
LEFT JOIN posts p ON p.community_id = c.id
LEFT JOIN likes l ON l.post_id = p.id
LEFT JOIN views v ON v.community_id = c.id
GROUP BY c.id, c.name, c.rating
ORDER BY likes_count DESC;
Результат
nameratingposts_countavg_scorelikes_countviews_count
TechTalks4.63933.367
GamersHub4.33906.765
PhotoWorld3.82830.043
TravelDiaries4.22825.012
FoodLovers4.12700.011
SportLife3.51720.000
05

Новые активные пользователи по месяцам

«Новый» пользователь — тот, кто поставил первый лайк в данном месяце. Смотрим, как растёт аудитория.

WITH first_like AS (
    SELECT
        user_id,
        MIN(liked_at)                            AS first_at,
        DATE_TRUNC('month', MIN(liked_at))::date AS cohort_month
    FROM   likes
    GROUP BY user_id
)
SELECT
    cohort_month,
    COUNT(*) AS new_users
FROM   first_like
GROUP BY cohort_month
ORDER BY cohort_month;
Результат
cohort_monthnew_users
2026-01-017
2026-02-012

7 пользователей сделали первый лайк в январе 2026, ещё 2 впервые проявили активность в феврале.

06

Бонус: ранжирование через оконные функции

Оконные функции (RANK, DENSE_RANK, ROW_NUMBER) позволяют ранжировать строки внутри групп, не теряя детализацию.

-- Ранг пользователей по лайкам внутри каждого города
SELECT
    u.name,
    u.city,
    COUNT(l.id)                                     AS likes_count,
    RANK()       OVER (PARTITION BY u.city ORDER BY COUNT(l.id) DESC) AS rnk,
    DENSE_RANK() OVER (PARTITION BY u.city ORDER BY COUNT(l.id) DESC) AS dense_rnk
FROM   users u
LEFT JOIN likes l ON l.user_id = u.id
GROUP BY u.id, u.name, u.city
ORDER BY u.city, rnk;
Результат (фрагмент)
namecitylikes_countrnkdense_rnk
ElviraKazan211
AndreyMoscow411
DmitriyMoscow222
IrinaMoscow133
MariaMoscow133
KateNovosibirsk311
NatalieNovosibirsk222
AnnaSaint Petersburg311
-- Накопительный итог лайков по датам
SELECT
    liked_at,
    COUNT(*)                              AS daily_likes,
    SUM(COUNT(*)) OVER (ORDER BY liked_at) AS cumulative_likes
FROM   likes
GROUP BY liked_at
ORDER BY liked_at;
Результат (фрагмент)
liked_atdaily_likescumulative_likes
2026-01-0122
2026-01-0313
2026-01-0714
2026-01-0837
2026-01-1029
2026-01-12312
2026-01-15113
2026-01-20215
2026-02-05116
2026-02-10117
2026-02-15118
SUM(COUNT(*)) OVER (ORDER BY liked_at) — оконная функция поверх агрегата. COUNT(*) агрегирует строки в группе, а SUM … OVER считает накопительный итог по всем группам в порядке даты.
Практические задания — на учебном портале. Задания, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.

Вы прошли курс!

За эти девять модулей вы освоили:

Следующий шаг — практика на реальных данных. Попробуйте Kaggle, public datasets PostgreSQL или откройте свою базу данных в pgAdmin и задайте ей правильные вопросы.

Модуль 08: Функции Все модули На главную