SQLab
УчёбаПрактикаЗадачиАренаРейтинг
© 2026 SQLab · Ташкент
SQLab

Учите SQL прямо в браузере — ничего не нужно устанавливать.

Платформа

  • Учёба
  • Практика
  • Задачи
  • Арена
  • Рейтинг

Для кого

  • Студентам
  • Преподавателям
  • Университетам
© 2026 SQLab. Все права защищены.Сделано в Узбекистане для студентов.
УчёбаПрактикаЗадачиАренаРейтинг
0/26

Основы

  • Что такое база данных?
  • Первый SELECT
  • WHERE: отбор нужных строк
  • IN, BETWEEN, LIKE и NULL
  • Сортировка, LIMIT и DISTINCT

Вычисления

  • Выражения, функции и CASE
  • Работа с датами
  • COUNT, SUM, AVG, MIN, MAX
  • GROUP BY и HAVING

Соединение таблиц

  • Ключи и связи
  • INNER JOIN
  • LEFT JOIN и строки без пары
  • Несколько таблиц и self join

Сложные запросы

  • Подзапросы
  • UNION, INTERSECT, EXCEPT
  • WITH: именованные запросы
  • Оконные функции

Создание и изменение таблиц

  • CREATE TABLE: типы и ограничения
  • INSERT, UPDATE, DELETE
  • ALTER, DROP, TRUNCATE
  • Как правильно спроектировать базу

Профессиональный уровень

  • Индексы и EXPLAIN
  • Транзакции и ACID
  • VIEW: сохранённые запросы
  • Функции, процедуры, триггеры
  • Пользователи, права и резервные копии
Учёба/Сложные запросы

Оконные функции

1711 мин

GROUP BY «сворачивает» строки в одну. Оконные функции оставляют каждую строку на месте и добавляют рядом расчёт по группе: место в рейтинге, нарастающий итог, значение из предыдущей строки.

Шаблон

функция() OVER (PARTITION BY группа ORDER BY порядок)
  • PARTITION BY — внутри каких групп считать (если не указать — весь результат одна группа);
  • ORDER BY — порядок внутри группы.

Места: ROW_NUMBER, RANK, DENSE_RANK

university· Попробуйте изменить
SELECT first_name, last_name, salary,
       ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_no,
       RANK()       OVER (ORDER BY salary DESC) AS rnk,
       DENSE_RANK() OVER (ORDER BY salary DESC) AS dense
FROM teachers
LIMIT 10;
  • ROW_NUMBER — 1, 2, 3… даже равным значениям разные номера;
  • RANK — равным одно место, следующее с пропуском (1, 1, 3);
  • DENSE_RANK — равным одно место, без пропуска (1, 1, 2).

Внутри каждой группы

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

university· Попробуйте изменить
WITH ranked AS (
  SELECT faculty_id, first_name, last_name, salary,
         RANK() OVER (PARTITION BY faculty_id ORDER BY salary DESC) AS rnk
  FROM teachers
)
SELECT faculty_id, first_name, last_name, salary FROM ranked WHERE rnk = 1;

Оконную функцию нельзя использовать в WHERE, поэтому сначала считаем её в CTE, а потом фильтруем.

Агрегат + OVER: доля и нарастающий итог

shop· Попробуйте изменить
SELECT c.name, COUNT(*) AS products,
       ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS share
FROM products p JOIN categories c ON c.id = p.category_id
GROUP BY c.name
ORDER BY products DESC;

SUM(...) OVER () — итог по всему результату рядом с каждой строкой.

Нарастающая выручка по месяцам:

taxi· Попробуйте изменить
WITH m AS (
  SELECT EXTRACT(MONTH FROM requested_at) AS mon, SUM(fare) AS revenue
  FROM trips
  WHERE status = 'completed' AND requested_at >= '2026-01-01'
  GROUP BY EXTRACT(MONTH FROM requested_at)
)
SELECT mon, revenue, SUM(revenue) OVER (ORDER BY mon) AS running_total
FROM m ORDER BY mon;

LAG и LEAD — соседняя строка

LAG(x) — значение из предыдущей строки, LEAD(x) — из следующей. Изменение по сравнению с прошлым месяцем:

taxi· Попробуйте изменить
WITH m AS (
  SELECT EXTRACT(MONTH FROM requested_at) AS mon, COUNT(*) AS trips
  FROM trips WHERE requested_at >= '2026-01-01'
  GROUP BY EXTRACT(MONTH FROM requested_at)
)
SELECT mon, trips, trips - LAG(trips) OVER (ORDER BY mon) AS diff
FROM m ORDER BY mon;
1Упражнение

Выведите first_name, last_name, salary каждого сотрудника и его место по зарплате во всей компании (DENSE_RANK, самая высокая — 1). По возрастанию места.


2Упражнение

Выведите id, first_name каждого студента и его место в своей группе: кто раньше поступил (enrolled_at) — тот первый, при равной дате — меньший id (ROW_NUMBER, PARTITION BY group_id).


Запомните

  • Оконная функция не сворачивает строки — она добавляет расчёт к каждой строке.
  • PARTITION BY — группа, ORDER BY — порядок.
  • Чтобы фильтровать по результату, сначала нужен CTE или подзапрос.
Предыдущий урокWITH: именованные запросыСледующий урокCREATE TABLE: типы и ограничения

Содержание

  • Шаблон
  • Места: ROW_NUMBER, RANK, DENSE_RANK
  • Внутри каждой группы
  • Агрегат + OVER: доля и нарастающий итог
  • LAG и LEAD — соседняя строка
  • Запомните
УчёбаПрактикаЗадачиАренаРейтинг

SQLab