
- Главная
- Каталог
- Интернет технологии
- SQL Academy: всё о реляционных БД и SQL
SQL Academy: всё о реляционных БД и SQL
Канал c очень активной аудиторией для аналитиков, программистов, тестировщиков и любого, кто стремится расширить свои знания в этой области. Высокая конверсия на рекламные предложения.
Статистика канала
А при мыслях об автоматизации задач и усилении своих скиллов, осекаешься - повышение квалифкации стоит десятки тысяч.
Больше 60% работодателей уже заложили бюджет на развитие команды в этом году. Просто большинство аналитиков никогда не просят. Потому что не знают, как.
Мы собрали полный гайд:
→ 8 шагов от «хочу прокачаться» до «компания всё оплатила»
→ Готовые обоснования для руководителя
→ Скрипты ответов на возражения
→ Чек-лист перед разговором с HR
Здесь - твоя грамотная заявка на корпоративный грант.
📄 Забирай методичку бесплатно → https://tglink.io/7516d0cb076c3f
Реклама. ООО "АЙТИ РЕЗЮМЕ". ИНН 4025460134. erid: 2W5zFHRhK4D
id name dept salary
1 Анна IT 80
2 Борис IT 120
3 Вера IT 150
4 Глеб HR 60
5 Дина HR 90{}
Ожидаемый результат:
dept median
IT 120 ← центр из 3
HR 75 ← (60+90)/2{}
Разбор
🧠 Что такое медиана на пальцах
🔹 Сортируем зарплаты по возрастанию
🔹 Если строк нечётно — берём центральную
🔹 Если чётно — среднее двух центральных
Для отдела с зарплатами [40, 50, 70, 100] медиана = (50 + 70) / 2 = 60.
1️⃣ Что нам нужно знать про каждую строку
Чтобы найти «центральную» строку в отделе, нужны две вещи:
🔹 её позиция в отсортированном списке внутри отдела
🔹 общее число строк в отделе
Обе задачи решают оконные функции — ROW_NUMBER() и COUNT(*) с PARTITION BY department.
2️⃣ Как найти центральные позиции
Формула для центра:
🔹 FLOOR((cnt + 1) / 2) — нижняя центральная
🔹 CEIL((cnt + 1) / 2) — верхняя центральная
Магия в том, что для нечётного cnt обе формулы дают одну и ту же строку — это и есть единственная центральная. Для чётного — две соседние, которые мы потом усредним.
Проверим на наших данных:
🔹 IT (cnt=3): FLOOR(4/2)=2, CEIL(4/2)=2 → берём строку №2 → зарплата 120 ✅
🔹 HR (cnt=2): FLOOR(3/2)=1, CEIL(3/2)=2 → строки №1 и №2 → (60+90)/2 = 75 ✅
3️⃣ Решение через оконные функции
WITH ranked AS (
SELECT
department,
salary,
ROW_NUMBER() OVER (
PARTITION BY department
ORDER BY salary
) AS rn,
COUNT(*) OVER (PARTITION BY department) AS cnt
FROM employees
)
SELECT
department,
AVG(salary * 1.0) AS median_salary
FROM ranked
WHERE rn IN (FLOOR((cnt + 1) / 2.0), CEIL((cnt + 1) / 2.0))
GROUP BY department;{}
CTE ranked внутри каждого отдела нумерует сотрудников от самой низкой зарплаты к самой высокой и параллельно считает общее число сотрудников. Внешний запрос оставляет только «центральные» строки и усредняет их.
На что обратить внимание
SELECT
department,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) AS median
FROM employees
GROUP BY department;{}
Но на собесе обычно просят именно «руками» — чтобы проверить, понимаете ли вы, что происходит под капотом 🔍
🎯 Что запомнить
🔹 Медиана руками = ROW_NUMBER + COUNT в одном CTE
🔹 Центральные позиции — FLOOR и CEIL от (cnt+1)/2
🔹 Делим на 2.0, а не на 2 — иначе целочисленное деление всё сломает
🔹 Если в БД есть PERCENTILE_CONT — используйте его; ручная реализация нужна только для собесов и старых MySQL (до 8.0 там вообще нет оконных функций — придётся через переменные)
Как это работает — коротко:
1. Таблица-клон
Rooms → триггер → Rooms_History
2. SYSTEM_TIME
Rooms → база сама ведёт историю
3. JSONB-слепки
Rooms → триггер → JSON-снимок в отдельную таблицу{}
1️⃣ Вариант 1: Таблица-клон
Самый понятный способ. Рядом с основной таблицей (например, Rooms) создаём её копию — Rooms_History. Каждый раз, когда кто-то меняет строку в основной таблице, автоматический механизм (триггер) сначала сохраняет старую версию строки в копию, и только потом применяет изменение.
Главная боль — Schema Drift. Допустим, разработчик добавил в основную таблицу новую колонку «площадь». Если он забыл добавить эту же колонку в таблицу-клон и обновить триггер — всё ломается. Подходит только там, где структура таблиц не менялась годами и не планирует.
2️⃣ Вариант 2: SYSTEM_TIME — встроенный видеорегистратор
Некоторые современные базы данных умеют вести историю сами, без всяких таблиц-клонов и триггеров. Достаточно один раз включить функцию — и база начнёт запоминать, когда каждая строка появилась и когда изменилась.
После этого можно буквально «заглянуть в прошлое» одной командой:
SELECT * FROM Rooms FOR SYSTEM_TIME AS OF '2026-01-01';{}
Эта строка говорит: «Покажи мне все комнаты в том виде, в каком они были 1 января 2026 года». Идеально для отладки: можно увидеть точное состояние данных в ту секунду, когда пользователь словил баг. Если нужна серьёзная аналитика и «путешествия во времени» — это лучший выбор.
Но есть нюанс: SYSTEM_TIME поддерживают не все базы данных. В PostgreSQL и MariaDB это работает, а вот в MySQL — нет.
3️⃣ Вариант 3: История через JSONB-слепки
Идея простая: каждый раз, когда строка меняется, мы берём её текущую версию, упаковываем целиком в один JSON-объект и сохраняем в отдельную таблицу. Если комнату не трогали полгода, ни одной новой записи за это время не появится.
Допустим, у комнаты №42 три раза менялась цена. В таблице истории будет:
room snapshot changed_at
42 {"price": 300, "status": "active"} 1 января
42 {"price": 400, "status": "active"} 15 марта
42 {"price": 500, "status": "paused"} 10 апреля{}
Хотим узнать цену в феврале? Берём последнюю запись до февраля — 300.
Почему JSON, а не обычная таблица-клон? Потому что JSON — это «резиновый» контейнер. Неважно, сколько новых колонок добавили в основную таблицу — JSON примет их все без единого изменения в таблице истории. Та самая проблема Schema Drift из первого варианта здесь просто не существует.
Ложка дёгтя: история раздувает базу
Об этом забывают чаще всего. Если данные меняются часто, таблица истории за полгода легко вырастает до сотен гигабайт.
Проверенная стратегия — разделять данные по «температуре»:
🔹«Горячая» история за последние 3 месяца — живёт в основной базе (PostgreSQL), к ней обращаются постоянно.
🔹 Всё, что старше — уезжает в «холодное» хранилище (ClickHouse, S3). Там место дешевле, а аналитика по миллионам старых строк работает даже быстрее.
Итого, что выбрать:
🔹 Простая система, структура не меняется → Таблица-клон с триггером
🔹 Нужна точная аналитика и «путешествие во времени» → SYSTEM_TIME
🔹 Структура часто меняется, средний масштаб → JSONB-слепки
И в любом случае — заранее решите, куда архивировать историю через год. Потом будет поздно.
CREATE VIEW active_users AS
SELECT * FROM Users WHERE deleted_at IS NULL;{}
Для решения конфликтов уникальности идеально подходят частичные индексы.
В Postgres это делается одной командой:
CREATE UNIQUE INDEX idx_email ON Users (email) WHERE deleted_at IS NULL;{}
Так индекс будет игнорировать удаленные строки. Это позволит пользователям регистрироваться заново на ту же почту и сэкономит место на диске.
Итог прост: если данные представляют хоть какую-то ценность, не удаляйте их. Используйте флаги удаления и View.
Это в разы безопаснее, чем чистить базу физически.Отзывы канала
всего 12 отзывов
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
SQL Academy: всё о реляционных БД и SQL — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 11.2K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 45.4, количество отзывов – 12, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 5314.68 ₽, а за 124 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий