Senior Data Analyst
779 subscribers
340 photos
9 videos
159 links
Data Analyst 360°
SQL, Python, ML, GPT, матстат и визуализация
BI, A/B, метрики, продуктовая аналитика
Для junior → middle → senior

Если хотите поддержать автора — здесь можно это сделать https://teletype.in/@seniorru

По вопросам: @seniorru
Download Telegram
🧠 SQL-фичи для ML — когда модель ещё не родилась, а фичи уже продовые

Все говорят про модели, а я напомню: ML — про стабильные фичи. И если ты собираешь их из SQL — значит, ты инженер. Или, как минимум, стал им на одну задачу.

Главное правило? Всё должно считаться быстро, воспроизводимо и объяснимо. Для этого у нас есть лучшие друзья — оконные функции.

▪️LAG / LEAD — прошлое и будущее без подзапросов

lag(amount) — выручка в прошлом заказе
lead(state) — что будет дальше
datediff(date, lag(date)) — сколько времени прошло

Фичи-паттерны:

• Прирост ((x - lag(x)) / lag(x))
• Флаг стабильности (abs(x - lag(x)) < 5)
• Смена поведения (lead(channel) <> channel)

Не забудь PARTITION BY, иначе будешь лагать глобально и ловить баги.


▪️AVG OVER / SUM OVER — скользящие фичи как по маслу

Rolling GMV, средний чек за 30 дней, вовлечённость по визитам — это всё ROWS BETWEEN …
avg(amount) over (
partition by user_id
order by order_date
rows between 6 preceding and current row
)

Почему это круче join’ов к календарю:

• Понятно глазу, приятно СУБД
• Поддерживается инкрементально
• Не ломается при обновлении


▪️Разности, дельты, тренды
(amount - lag(amount)) / nullif(lag(amount), 0)

Это база:

• Падение или рост
• Отклонение от медианы
• Тренд за последние 3 точки

Для ML — фичи без переобучения.


▪️RANK, ROW_NUMBER, NTILE — не просто ранги

rank() over (...) — кто топ
ntile(5) — к какому сегменту относится
row_number() — какое по счёту событие

Фичи:

• ТОП‑1 активность
• Покупка до/после акции
• Сколько раз человек кликал перед конверсией


▪️Зачем SQL-инженер в ML вообще?

• фичи стабильны и понятны
• код читается даже через 3 недели
• можно отлаживать руками, без Jupyter

Потому что ML без витрины — это pet‑проект.
А продовая модель начинается с продовых данных.

Если ты хоть раз считал lag() в витрине — ты уже ближе к ML, чем думаешь.
Осталось это просто задокументировать и покрыть тестом 😉

💥 Как тебе эта тема?
🔥 — узнал(а) что-то новое
🤝 — тема хорошо знакома

Оставь реакцию — это как тест: сразу видно, где работает, а где надо переделать

💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥61
🧠 SQL: Как отлаживать вложенные запросы — стратегия снизу вверх

Ты смотришь на CTE, в котором CTE, внутри которого подзапрос. Запускаешь — а результат странный. Где ошибка? В фильтре? В агрегации? Или ты просто отрезал всё условием WHERE?

📌 В посте:
— 3 сценария, где всё ломается, и как это отладить
— Почему count(*) — лучший друг аналитика
— Как читать вложенные запросы в обратном порядке и не сойти с ума

Senior не «смотрит глазами финального SELECT». Он раскладывает код на слои, как луковицу 🧅 Проверяет каждый уровень руками. Потому что баги почти никогда не на поверхности.

💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥5
🧠 Часть 2: Мышление «снизу вверх» — как отлаживать SQL, как инженер

Когда ты пишешь или читаешь SQL, легко застрять на финальном SELECT — он вроде работает, а результат кажется знакомым. Но настоящий мастер сыщет проблему в самом начале: ближе к истоку. Потому что каждая CTE и подпроекция — это свой слой данных, своя реальность. И именно там часто затаился баг.

▪️Стратегия: снизу вверх — debugger по-аналитически
1. Идентифицируй самый глубокий блок — крайний CTE или вложенный SELECT.
2. Запускай его отдельно — проверь, что данные действительно есть, что поля не пустые, что типы такие, как ожидаешь.
3. Переходи дальше — следующий уровень CTE. Смотри, как меняются строки, агрегаты, возможные дубли.
4. На каждом шаге добавляй COUNT(*), LIMIT 10, ORDER BY — чтобы увидеть структуру, а не лишь числа.
5. Сверяй результат с ожиданиями — руками или BI визуализацией.

▪️Типичные ловушки и как их заметить
WHERE отрезал всё
Что случилось: слишком строгие условия или NULL
Как видно: таблица или CTE возвращает 0 строк


Дубли из-за JOIN
Что случилось: не учёл 1:N‑связь
Как видно: COUNT больше ожидаемого, строки повторяются


LAG / LEAD без ORDER BY
Что случилось: оконная функция без сортировки
Как видно: значения хаотичные или NULL, хотя не должны


SUM / AVG не то
Что случилось: агрегация не на том уровне
Как видно: средние странные, выбросы, неверная разбивка


▪️ Почему я думаю, что это работает
Изоляция багов. Легко понять, где начинает «происходить магия».
Чувство контроля. Видишь, сколько строк, какие поля, как образуется итоговая таблица.
Пошаговая стратегия. Не паникуешь, а действуешь по контрольному листу.

▪️Быстрые хаки для ускорения:
• В IDE выделяешь CTE и исполняешь — наблюдаешь выборку.
• Вставляешь COUNT() и TABLESAMPLE — сразу смотришь, не объелся ли он данными.
• Комментируешь финальный SELECT и выполняешь промежуточные слои — быстро адаптируешь.

▪️ Senior-разводка: код работать не значит работать правильно
• Проверил CTE — и упало? Это хорошо — стало понятно где.
• Всё «кажется нормальным», но итог не тот? — значит баг спрятан глубже.
• ИТ-шутка «Предположение ≠ данные» — про SQL.

Вывод:
Отладка SQL — методичная игра «от источника до финала». Стратегия «снизу вверх» — это твоя армия: она делает сложную логику понятной, воспроизводимой и уверенной. И да — это именно тот скилл, который отличает тебя от случайного «тыкающей кнопки» в BI

💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥3👍2
🎯 3 задачи, после которых ты точно не скажешь "я аналитик-любитель"

Хочешь проверить, джун ты или уже почти бог дата-инженерии? Погнали:

▪️Junior
Классика: найди тех, у кого >3 заказа за 30 дней.
Фильтрация, группировка, агрегация — ну ты понял.
Если не понял — точно джун

▪️Middle
Когортный анализ.
Pivot, даты, удержание — тот случай, когда таблицы становятся интригой.
Почувствуй себя аналитиком стартапа на грани успеха.

▪️Senior
Pydantic, валидация, conint(gt=0) — кайф для тех, кто любит, чтоб всё чётко.
Если ты валидировал хоть раз JSON на проде — ты в клубе.

💸 Поддержать канал и скачать .ipynb можно уже с шаблонами, проверками и баллами - тут 😌

Сделал — респект.
Завтыкал — попробуй ещё.
В любом случае: весело, больно, по-настоящему.

👉 Senior Data Analyst | #python
🔥9
🧠 Почему аналитик должен знать Airflow
Или как перестать быть ручным исполнителем скриптов

▪️Cron — это не автоматизация. Это ловушка.
Ты вроде бы всё настроил, но…
— логов нет
— ретраев нет
— зависимости мимо
— мониторинг — руками
— и вообще непонятно, что пошло не так 😵‍💫
В итоге аналитик вручную запускает скрипт, потому что «крон опять не сработал».

▪️ Что даёт Airflow?
Airflow — это не просто планировщик, а полноценная система исполнения задач. Он:
понимает зависимости (запусти шаг 2 только после успешного шага 1)
оборачивает код в управляемые блоки (Python, Bash, SQL — на выбор)
даёт отладку и мониторинг (UI, stacktrace, перезапуск одной задачи)
хранит историю запусков (можно посмотреть, что падало месяц назад)
дружит с расписаниями и шаблонами (@daily, {{ ds }})

▪️ Что можно автоматизировать
Не только ETL, но и:
• выгрузки и пересчёты
• алёрты по данным
• обновление отчётов
• ML-пайплайны
• проверки и напоминания

💸 Поддержать канал
👉 Senior Data Analyst | #python
🔥3👌3
🧠 Airflow и Pandas — мощная связка для аналитика.

В этом DAG мы качаем данные из API, обрабатываем в Pandas и сохраняем в Excel.
Расписание, логи, структура raw → processed, типизация и надёжность.
Идеальный шаблон для автоматизации отчётов, парсинга и ETL.

💸 Поддержать канал
👉 Senior Data Analyst | #python
🔥4👍3
Зачем вообще DAG для Pandas?

У каждого аналитика есть «та самая папка со скриптами».
API, Excel, выгрузки, подсчёты, пересчёты — всё вручную. Потом через cron. Но если честно — пора переходить на DAG.

Этот пример показывает, как из ручного ETL сделать стабильный, управляемый и приятный пайплайн, который:
• выполняется по расписанию
• логирует каждый шаг
• сохраняет результат по структуре
• валится с ошибкой, если что-то пошло не так
• и вообще выглядит по-взрослому

Как устроен код?

1️⃣ fetch_data
Качает данные из https://dummyjson.com/products
→ Превращает JSON в pandas.DataFrame
→ Сохраняет как data/raw/products_<ds>.csv
→ Использует дату из контекста (context["ds"]) — то есть работает "по календарю"

2️⃣ process_data
→ Читает csv, считает price_with_tax
→ Сохраняет результат в data/processed/products_cleaned_<ds>.xlsx
→ Демонстрирует, как можно обрабатывать данные Pandas внутри DAG

3️⃣ DAG
→ Запускается ежедневно (@daily)
→ Использует PythonOperator
→ Передаёт дату через контекст (магия, но понятная)


▪️ Структура данных выглядит вот так:
/opt/airflow/data/
├── raw/
│ └── products_2025-07-22.csv
└── processed/
└── products_cleaned_2025-07-22.xlsx

Чёткое разделение на raw и processed
Можно вернуться к исходнику, пересчитать, проверить. Красота.

▪️Почему это лучше, чем просто скрипт fetch_and_process.py?
Ну смотри, что ты получаешь с Airflow:
• Ретрай, если API временно отвалился
• Контроль за успехом выполнения
• Отправку алёртов, если что-то пошло не так
• Удобный UI — наглядно видно, что работает, а что нет
• Логи — по каждому шагу, с ошибками, stacktrace и временем

И всё это — автоматически. Просто потому что ты перешёл от «файлика» к DAG.

▪️Как адаптировать под свои задачи?
Airflow гибкий. Меняешь куски — и вуаля:
• вместо Excel → пишем в ClickHouse, PostgreSQL или в облако
• вместо API → читаем Google Sheets, S3, базы
• вместо Pandas → ставим Polars или SQLAlchemy

DAG — это про структуру.

▪️А что насчёт прикладной аналитики?
Вот реальные кейсы:

• Парсинг прайс-листов → автоматическая сводка изменений
• Проверка API магазинов → алёрт, если скидки исчезли
• Сводка по REST-запросам → Excel-отчёт или сообщение в мессенджер

Всё, что раньше делалось вручную — теперь живёт в пайплайне. И ты не вспоминаешь про него, пока не придёт алёрт.

▪️Главный вывод
Airflow — это не только для big data и дата-инженеров.
Это про предсказуемость, контроль.

Если ты один раз скачал и обработал файл — да, это скрипт.
Но если ты делаешь это каждый день — это уже DAG. И его пора так оформить.

💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы

💸 Поддержать канал
👉 Senior Data Analyst | #python
🔥11
Продолжение следует....
👍8
🧠 Python для аналитиков: if, elif, else — без боли
Когда «управление логикой» звучит не как философия, а как реальный навык

Это первая серия модуля 3 — и она про то, как писать условия, не превращаясь в программиста 2008 года.

Что внутри:
→ на пальцах объясняем, как работает if, elif, else
→ 10 примеров с комментариями: от “число положительное?” до “если всё сложно, делай красиво
→ практическое задание: определяем возрастную категорию
→ советы и фейлы: как не закопаться в условиях и не получить else: print('что-то пошло не так')
→ реальный кейс: расчёт налога по типу дохода, возрасту и льготам — пригодится даже в жизни

Это не учебник. Это фундамент.
После этой серии if перестанет быть пугающим, а начнёт работать на вас.

💸 Поддержать канал и скачать серию можно здесь
📣 И да, поставь реакцию за старание

👉 Senior Data Analyst | #python #модуль_03 #серия_01
🔥65
🧠 Как писать свои SQL‑функции в PostgreSQL — и зачем это нужно?

Собрали прод‑разбор:
– scalar, plpgsql и TVF функции с реальными кейсами;
– зачем нужны IMMUTABLE и STABLE;
– как вынести бизнес‑логику в UDF и перестать дублировать CASE‑ы;
– примеры для сегментации, нормализации, топ‑N.

Сделайте свои витрины легче, код — чище, и отчёты — стабильнее.

💸 Поддержать канал
👉 Senior Data Analyst | #sql
👍9
🧠 Зачем вообще SQL-функции, если можно просто написать SELECT?

На ранних этапах всё просто: CASE WHEN, пара JOIN-ов, и ты доволен.
Но с ростом проекта — и твоим опытом — появляется ощущение, что код начинает душить.


Когда проект растёт, вместе с ним растёт и боль:
• дублирующаяся логика
• громоздкие CASE WHEN
• правила, разбросанные по десяткам CTE
• метрика меняется — ты бегаешь по скриптам с огнетушителем

Вот тут и заходят на сцену SQL-функции (UDF).
Они позволяют вынести логику в одно место. Изолированно. Переиспользуемо. Как функции в коде, только внутри БД.

▪️ Какие бывают функции в PostgreSQL?
• Скалярные
normalize(score, avg, sd) → возвращают одно значение
Используются в метриках, флагах, категоризациях

• Табличные
top_n_per_category(n) → возвращают таблицу
Удобны для создания витрин и кастомных выборок с параметрами

• Агрегатные
my_median(val) → агрегируют значения
Нужны, если стандартных агрегатов мало или не подходят


▪️Реальные кейсы
1️⃣ Категоризация пользователей
Было: CASE WHEN spend > 10000 AND visits > 5 THEN 'VIP' ...
Стало: customer_segment(spend, visits)
→ читается, тестируется, правится в одном месте

2️⃣ Флаг аномалии
is_outlier(val, avg, stddev)

→ можно использовать в WHERE, CASE, JOIN, даже в dbt-тестах

3️⃣ Параметризуемая витрина
SELECT * FROM top_n_per_category(3)

→ больше не пишешь ROW_NUMBER вручную в каждом скрипте

▪️IMMUTABLE, STABLE, VOLATILE — важнее, чем кажется
IMMUTABLE — всегда даёт одинаковый результат при одних и тех же аргументах
→ используется для расчётов (abs(x), normalize(...))

STABLE — может читать таблицы, но не меняет данные
→ подходит для SELECT ... WHERE id = x

VOLATILE — может вести себя непредсказуемо
random(), now(), count(*)

Если не указать тип, PostgreSQL подставит VOLATILE, и оптимизации не будет. А это уже тормоза.


▪️Тестирование UDF
Функции можно (и нужно) тестировать:
• pgTAP — юнит-тесты прямо в PostgreSQL
• ручные тесты через begin...end
• автотесты через CI: пушнул код — сравнил результат
SELECT customer_segment(11000, 6) = 'VIP' AS test_1;


▪️Как устроено в проде
1. Версионирование
segment_v1, segment_v2, segment_active
→ переключаешь alias, не ломаешь пайплайн

2. Интеграция с dbt и Airflow
→ в dbt — используешь как обычную функцию
→ в Airflow — вызываешь в PostgresOperator

3. Документация
COMMENT ON FUNCTION внутри тела
→ changelog логики — в доках проекта


▪️Типичные ошибки

• писать скалярную функцию, которая делает SELECT
→ это отдельный запрос на каждую строку → тормозит

• не указывать IMMUTABLE или STABLE
→ теряется кеш, растёт нагрузка

• изменять функции без версионирования
→ одно изменение — и всё падает

• писать гигантские UDF без профилирования
→ сложно читать, плохо оптимизируется

▪️Вывод

SQL-функции — про стабильность, переиспользуемость и контроль.

Они дают тебе одно: уверенность, что логика работает так, как ты задумал. И что её не нужно чинить каждую неделю.

💸 Поддержать канал
👉 Senior Data Analyst | #sql
8👍1
🧠 Погнали разогревать мозги — задачи ждут!

Если и есть день для чётких решений — это сегодня. Среда, энергия есть, мозг включён!


💸 Поддержать канал
👉 Senior Data Analyst | #матстат #теорвер
🔥6