Какой у вас уровень владения SQL?

Ответ

Уровень: Intermediate/Advanced. Могу составлять сложные аналитические запросы, оптимизировать их и понимаю принципы работы СУБД.

Ключевые навыки:

  • Сложные операции выборки: JOIN (INNER, LEFT, RIGHT, FULL, CROSS), подзапросы (коррелированные и некоррелированные), UNION.
  • Агрегация и анализ: GROUP BY, агрегатные функции (SUM, COUNT, AVG), FILTER (WHERE), HAVING.
  • Оконные функции (Window Functions): ROW_NUMBER(), RANK(), DENSE_RANK(), LAG(), LEAD(), SUM() OVER(PARTITION BY ...).
  • Модификация данных: INSERT, UPDATE, DELETE, MERGE (UPSERT).
  • Управление данными: Транзакции (BEGIN, COMMIT, ROLLBACK), представления (VIEW), CTE (Common Table Expressions).
  • Оптимизация: Понимание индексов (B-tree, составные), анализ планов выполнения (EXPLAIN, EXPLAIN ANALYZE), избегание N+1 проблем.

Пример запроса с оконной функцией для анализа пользовательской активности:

WITH user_activity AS (
    SELECT
        user_id,
        DATE(login_time) AS login_date,
        COUNT(*) AS daily_logins
    FROM user_sessions
    WHERE login_time >= CURRENT_DATE - INTERVAL '30 days'
    GROUP BY user_id, DATE(login_time)
)
SELECT
    user_id,
    login_date,
    daily_logins,
    -- Скользящее среднее за 7 дней
    AVG(daily_logins) OVER (
        PARTITION BY user_id
        ORDER BY login_date
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS avg_logins_7d,
    -- Ранг активности пользователя за день
    RANK() OVER (
        PARTITION BY login_date
        ORDER BY daily_logins DESC
    ) AS daily_rank
FROM user_activity
ORDER BY user_id, login_date;

Имею опыт работы с PostgreSQL, MySQL, SQLite.

Ответ 18+ 🔞

А, ну ты, я смотрю, SQL-шаман уровня «я тебе тут оконную функцию на коленке напишу, пока ты кофе не допил». Красава, чё. Сложные запросы — это как высший пилотаж, только вместо самолёта — таблицы, а вместо земли — полная жопа, если JOIN неправильно напишешь.

Слушай, смотрю на твои навыки и думаю: «Ёпта, да этот чувак с базой на „ты“, и база ему, сука, отвечает». JOIN'ы всякие, подзапросы, агрегация... Это ж не просто SELECT * FROM users WHERE brain > 0. Это уже искусство, блядь.

Оконные функции — это вообще отдельная песня. Это когда тебе надо не просто посчитать, а посчитать умно, с прицелом, с оглядкой на соседей по партиции. Как будто ты не просто бухаешь, а бухаешь с анализом: «А сколько в среднем выпил Вася за последние 7 дней, и какой у него рейтинг среди алкашей района?». Вот это уровень!

И оптимизация... О, это святое. EXPLAIN ANALYZE — это как рентген для запроса. Смотришь на план и понимаешь: «Ага, сука, тут Seq Scan на овердохуища строк, потому что индекс проёбан». Идешь, создаёшь индекс, и запрос из черепахи превращается в гепарда. Красота.

Твой пример запроса — это просто пиздец как элегантно. CTE для подготовки, потом скользящее среднее, да ещё и ранжирование. Прям вижу, как какой-нибудь менеджер смотрит на этот daily_rank и охуевает: «Вася, ты у нас сегодня чемпион по логинам!».

-- Код, блядь, не трогаем. Он и так идеален.
WITH user_activity AS (
    SELECT
        user_id,
        DATE(login_time) AS login_date,
        COUNT(*) AS daily_logins
    FROM user_sessions
    WHERE login_time >= CURRENT_DATE - INTERVAL '30 days'
    GROUP BY user_id, DATE(login_time)
)
SELECT
    user_id,
    login_date,
    daily_logins,
    AVG(daily_logins) OVER (
        PARTITION BY user_id
        ORDER BY login_date
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS avg_logins_7d,
    RANK() OVER (
        PARTITION BY login_date
        ORDER BY daily_logins DESC
    ) AS daily_rank
FROM user_activity
ORDER BY user_id, login_date;

PostgreSQL, MySQL... Да похуй, в принципе. Главное — понимать, как эта штука изнутри работает. А то знаешь же, как бывает: пишешь запрос в SQLite, а он работает, а потом переносишь на PostgreSQL, а там какая-нибудь мелочь, типа LIMIT/OFFSET в подзапросе, и всё, пизда, приехали. Но ты, я смотрю, в теме. Так что давай, делай свои MERGE и катай ROLLBACK'и, если чё. Главное — транзакции не забудь завершить, а то залочишь всё нахуй.