🧠 Python для аналитиков: циклы без лишнего кода
for, while и идиоматичный Python — вживую, по делу
Это вторая серия модуля 3, и она про то, как писать циклы так, чтобы не стыдно было.
генераторы,
Задачи:
— фильтрация CSV,
— отчёт по продажам,
— имитация банкомата (с ошибками, как в жизни)
После этой серии ты забудешь, как выглядят "петли ада" и начнёшь писать коротко, понятно и без лишних if'ов.
💸 Поддержать канал, сказать «ну кайф» и скачать серию можно тут
❤️ И да, поставь реакцию за старание
👉 Senior Data Analyst #python #модуль_03 #серия_02
for, while и идиоматичный Python — вживую, по делу
Это вторая серия модуля 3, и она про то, как писать циклы так, чтобы не стыдно было.
for
— от списков до словарей, с zip() и enumerate()while
— когда не знаешь, сколько раз, но точно надогенераторы,
any
, all
, sorted
— чтоб писать красивоЗадачи:
— фильтрация CSV,
— отчёт по продажам,
— имитация банкомата (с ошибками, как в жизни)
После этой серии ты забудешь, как выглядят "петли ада" и начнёшь писать коротко, понятно и без лишних if'ов.
💸 Поддержать канал, сказать «ну кайф» и скачать серию можно тут
❤️ И да, поставь реакцию за старание
👉 Senior Data Analyst #python #модуль_03 #серия_02
5❤7
⚠️ Три SQL-ловушки даже для опытных
1. LEFT JOIN, который стал INNER
Думал, берёшь всех пользователей, даже без заказов? А фильтр по правой таблице в WHERE выкинул NULL-ы — и всё, отчёт «похудел».
Если нужен INNER — пиши его явно.
2. DISTINCT как пластырь
Дубликаты? DISTINCT скроет их, но не исправит причину — кривые ключи или «многие-ко-многим». На больших объёмах ещё и тормозит.
Найди и почини источник дублей.
3. Фильтры, что убивают индексы
Убирай функции из фильтров или храни отдельные поля для поиска.
💸 Поддержать канал
👉 Senior Data Analyst | #sql
1. LEFT JOIN, который стал INNER
Думал, берёшь всех пользователей, даже без заказов? А фильтр по правой таблице в WHERE выкинул NULL-ы — и всё, отчёт «похудел».
Если нужен INNER — пиши его явно.
2. DISTINCT как пластырь
Дубликаты? DISTINCT скроет их, но не исправит причину — кривые ключи или «многие-ко-многим». На больших объёмах ещё и тормозит.
Найди и почини источник дублей.
3. Фильтры, что убивают индексы
DATE(col) = '2025-01-01'
или LIKE '%abc'
лишают индекс шанса работать. На тестах всё быстро, а на проде — скан миллионов строк.Убирай функции из фильтров или храни отдельные поля для поиска.
💸 Поддержать канал
👉 Senior Data Analyst | #sql
👍5🤔1
⚠️ SQL и три ловушки, которые должен видеть Senior
▪️Почему важно копать глубже?
На ревью SQL‑кода легко проверить только синтаксис, названия колонок и то, что результат «похож» на ожидаемый. Но на уровне senior задачи другие:
• Проверить бизнес‑логику — запрос должен возвращать ровно то, что задумано.
• Обеспечить инженерное качество — избежать скрытых ошибок и деградации.
• Гарантировать читаемость — код должны понимать и поддерживать другие.
SQL‑запросы редко живут сами по себе: они попадают в витрины, отчёты, фичи для моделей. Любой компромисс «на авось» со временем размножается и становится проблемой.
▪️Ловушка 1: LEFT JOIN, который «тихо» стал INNER
Симптом: используется LEFT JOIN, но в WHERE добавлен фильтр по колонке правой таблицы. Это меняет смысл соединения — строки без совпадений исчезают.
Опасность:
• Тихое искажение логики: запрос, который должен возвращать всех клиентов, внезапно отбрасывает часть.
• Проблема заметна не сразу — в отчётах «пропадают» данные.
• Разные ожидания у участников команды.
Как обнаружить: при ревью искать конструкции
Что делать:
• Переносить условие в ON, если оно относится к соединению.
• Если соединение должно быть INNER, писать явно.
• Для сложных фильтров предварительно отфильтровать данные правой таблицы.
▪️Ловушка 2: DISTINCT как «пластырь» на неправильный JOIN
Симптом: DISTINCT или COUNT(DISTINCT) в запросе для устранения дублей.
Опасность:
• Скрывает причину дубликатов — чаще всего это неправильные ключи или соединение «многие‑ко‑многим».
• DISTINCT замедляет выполнение на больших объёмах.
• Может приводить к потере нужных данных.
Как обнаружить: задать вопрос автору: «Почему тут DISTINCT?». Проверить кардинальность соединений и условия.
Что делать:
• Явно выбирать одну нужную строку с помощью оконных функций или подзапросов.
• Агрегировать данные до соединения.
• Использовать DISTINCT только там, где это действительно часть бизнес‑логики.
▪️Ловушка 3: Несаржабельные фильтры, которые убивают индексы
Симптом: в WHERE применяются функции к колонкам, используется LIKE с ведущим %, или происходит приведение типов на лету.
Опасность:
• Индекс по колонке не используется.
• На тестах запрос быстрый, а на бою уходит в полное сканирование.
• Проблема проявляется при росте объёмов данных.
Как обнаружить: искать функции в фильтрах
Что делать:
• Переписывать фильтры, чтобы индекс мог быть использован (работать с диапазонами дат, хранить предрасчитанные значения).
• Денормализовать часто фильтруемые значения (например, выделить домен email в отдельную колонку).
• Использовать специализированные индексы (GIN, BRIN, trigram).
▪️ Чек‑лист Senior на ревью SQL
• LEFT JOIN + WHERE по правой таблице? → проверить логику.
• DISTINCT / COUNT(DISTINCT)? → действительно ли нужен.
• Кардинальность соединений ясна и контролируема.
• Функции на колонках в WHERE? → переписать под индексы.
• LIKE с ведущим %? → оптимизировать.
• Индексы соответствуют условиям фильтрации.
• План запроса не ушёл в Seq Scan без причины.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
💸 Поддержать канал
👉 Senior Data Analyst | #sql
Разбор трёх частых анти‑паттернов в SQL, которые встречаются даже у опытных разработчиков. Почему они опасны, как их заметить на ревью и что с ними делать.
▪️Почему важно копать глубже?
На ревью SQL‑кода легко проверить только синтаксис, названия колонок и то, что результат «похож» на ожидаемый. Но на уровне senior задачи другие:
• Проверить бизнес‑логику — запрос должен возвращать ровно то, что задумано.
• Обеспечить инженерное качество — избежать скрытых ошибок и деградации.
• Гарантировать читаемость — код должны понимать и поддерживать другие.
SQL‑запросы редко живут сами по себе: они попадают в витрины, отчёты, фичи для моделей. Любой компромисс «на авось» со временем размножается и становится проблемой.
▪️Ловушка 1: LEFT JOIN, который «тихо» стал INNER
Симптом: используется LEFT JOIN, но в WHERE добавлен фильтр по колонке правой таблицы. Это меняет смысл соединения — строки без совпадений исчезают.
Опасность:
• Тихое искажение логики: запрос, который должен возвращать всех клиентов, внезапно отбрасывает часть.
• Проблема заметна не сразу — в отчётах «пропадают» данные.
• Разные ожидания у участников команды.
Как обнаружить: при ревью искать конструкции
LEFT JOIN
+ фильтр по колонкам правой таблицы в WHERE.Что делать:
• Переносить условие в ON, если оно относится к соединению.
• Если соединение должно быть INNER, писать явно.
• Для сложных фильтров предварительно отфильтровать данные правой таблицы.
▪️Ловушка 2: DISTINCT как «пластырь» на неправильный JOIN
Симптом: DISTINCT или COUNT(DISTINCT) в запросе для устранения дублей.
Опасность:
• Скрывает причину дубликатов — чаще всего это неправильные ключи или соединение «многие‑ко‑многим».
• DISTINCT замедляет выполнение на больших объёмах.
• Может приводить к потере нужных данных.
Как обнаружить: задать вопрос автору: «Почему тут DISTINCT?». Проверить кардинальность соединений и условия.
Что делать:
• Явно выбирать одну нужную строку с помощью оконных функций или подзапросов.
• Агрегировать данные до соединения.
• Использовать DISTINCT только там, где это действительно часть бизнес‑логики.
▪️Ловушка 3: Несаржабельные фильтры, которые убивают индексы
Симптом: в WHERE применяются функции к колонкам, используется LIKE с ведущим %, или происходит приведение типов на лету.
Опасность:
• Индекс по колонке не используется.
• На тестах запрос быстрый, а на бою уходит в полное сканирование.
• Проблема проявляется при росте объёмов данных.
Как обнаружить: искать функции в фильтрах
(DATE(col)
, LOWER(col))
, проверять шаблоны поиска, смотреть план запроса.Что делать:
• Переписывать фильтры, чтобы индекс мог быть использован (работать с диапазонами дат, хранить предрасчитанные значения).
• Денормализовать часто фильтруемые значения (например, выделить домен email в отдельную колонку).
• Использовать специализированные индексы (GIN, BRIN, trigram).
▪️ Чек‑лист Senior на ревью SQL
• LEFT JOIN + WHERE по правой таблице? → проверить логику.
• DISTINCT / COUNT(DISTINCT)? → действительно ли нужен.
• Кардинальность соединений ясна и контролируема.
• Функции на колонках в WHERE? → переписать под индексы.
• LIKE с ведущим %? → оптимизировать.
• Индексы соответствуют условиям фильтрации.
• План запроса не ушёл в Seq Scan без причины.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
💸 Поддержать канал
👉 Senior Data Analyst | #sql
🔥9🤝1
💬 Почему сеньор не отвечает на задачу сразу?
Потому что сначала уточняет, что именно нужно.
На первый взгляд кажется, что он просто тянет время.
А на деле — экономит и своё, и твоё время.
Размытый запрос = риск запутаться в терминах, насыпать лишних данных и угробить пару часов впустую.
Обычно вопросы такие:
• Зачем нужны эти данные?
• Какие именно поля важны?
• В каком виде будет удобнее получить результат?
• Когда это критично?
💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
Потому что сначала уточняет, что именно нужно.
На первый взгляд кажется, что он просто тянет время.
А на деле — экономит и своё, и твоё время.
Размытый запрос = риск запутаться в терминах, насыпать лишних данных и угробить пару часов впустую.
Обычно вопросы такие:
• Зачем нужны эти данные?
• Какие именно поля важны?
• В каком виде будет удобнее получить результат?
• Когда это критично?
2 минуты на уточнения = часы, сэкономленные на переделках.
Это не бюрократия, а страховка от бессмысленной работы.
💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
🔥4🤝1
🐢 Почему сеньор не отвечает сразу: искусство уточнять задачу
Сеньор-аналитик — это не «гуру SQL, который помнит все джоины наизусть».
Это человек, который сначала задаёт вопросы, а уже потом открывает SQL.
1. Миф о «быстром ответе»
Во многих командах ценится оперативность:
Но скорость ≠ ценность.
Можно потратить 10 минут на запрос, который:
• никому не нужен в таком виде;
• считает не те поля;
• не решает исходную задачу.
В итоге — переделки, двойная работа и раздражение.
Поэтому начинаем не с кода, а с уточнений.
2. Зачем вообще уточнять
Часто заказчик описывает решение, а не проблему.
Пример:
А на самом деле может быть, что:
• нужен расчёт churn rate;
• интересуют только активные клиенты;
• речь про конкретный сегмент;
• цель — слайд для совета директоров.
А значит фильтруем всё через призму:
• Что хотим понять?
• Почему нужны именно эти данные?
• Как это повлияет на решение?
3. Как это выглядит на разных уровнях
→ Джун — берёт задачу как есть, максимум уточняет формат и дедлайн.
→ Мидл — спрашивает про поля, источники, фильтры; понимает ценность данных, но не всегда видит весь контекст.
→ Сеньор — выясняет цель, согласует метрики, проверяет, есть ли готовое решение, и предлагает самый удобный способ.
4. Мини-фреймворк SCOPE
S — Scope: объём, сегменты, периоды, фильтры.
C — Context: какую проблему решаем и кто примет решение.
O — Output: формат — выгрузка, дашборд, автоотчёт.
P — Priority: как это по срочности относительно других задач.
E — Exceptions: что исключаем, какие риски.
5. Кейсы
📍 Из выгрузки в дашборд
Запрос: «Скинь продажи по регионам за прошлый месяц».
После уточнений: нужен еженедельный мониторинг + доступ для 3 отделов → сделали дашборд в Tableau, экономим 15 часов в месяц.
📍 Уточнение спасло от спама мёртвым клиентам
Запрос: «Клиенты без покупок 6+ месяцев».
После уточнений: добавили фильтр “открывал рассылки за 3 месяца” → в кампанию попали только живые пользователи.
6. Когда не уточняешь
• Размытые термины («активный клиент» = разные цифры у разных команд).
• Неверный период (30 дней ≠ календарный месяц).
• Игнор контекста (миллиард строк вместо нужной агрегации).
• Срыв приоритетов (взялся за «срочную» задачу и завалил реально важную).
7. Как прокачать навык
• Не бойся казаться медленным — страшнее сделать бесполезно.
• Используй чек-лист вопросов.
• Переформулируй задачу и жди подтверждения.
• Веди базу определений метрик.
8. Пример живого диалога
— Скинь продажи по Москве за прошлый квартал.
— А для чего? Отчёт или анализ трендов?
— Для презентации руководству.
— Сравнение с прошлым кварталом или и с прошлым годом?
— И с годом тоже.
— Таблица или график?
— График.
Запрос → Excel
Результат → график с трендом и комментариями прямо в презентации.
Попробуй: на каждый новый запрос — задай хотя бы 3 уточняющих вопроса.
Посмотри, сколько переделок удастся избежать.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
Сеньор-аналитик — это не «гуру SQL, который помнит все джоины наизусть».
Это человек, который сначала задаёт вопросы, а уже потом открывает SQL.
1. Миф о «быстром ответе»
Во многих командах ценится оперативность:
— «Попросили выгрузку — сделал за 10 минут».
Но скорость ≠ ценность.
Можно потратить 10 минут на запрос, который:
• никому не нужен в таком виде;
• считает не те поля;
• не решает исходную задачу.
В итоге — переделки, двойная работа и раздражение.
Поэтому начинаем не с кода, а с уточнений.
2. Зачем вообще уточнять
Часто заказчик описывает решение, а не проблему.
Пример:
«Скинь выгрузку по клиентам за прошлый месяц».
А на самом деле может быть, что:
• нужен расчёт churn rate;
• интересуют только активные клиенты;
• речь про конкретный сегмент;
• цель — слайд для совета директоров.
А значит фильтруем всё через призму:
• Что хотим понять?
• Почему нужны именно эти данные?
• Как это повлияет на решение?
3. Как это выглядит на разных уровнях
→ Джун — берёт задачу как есть, максимум уточняет формат и дедлайн.
→ Мидл — спрашивает про поля, источники, фильтры; понимает ценность данных, но не всегда видит весь контекст.
→ Сеньор — выясняет цель, согласует метрики, проверяет, есть ли готовое решение, и предлагает самый удобный способ.
4. Мини-фреймворк SCOPE
S — Scope: объём, сегменты, периоды, фильтры.
C — Context: какую проблему решаем и кто примет решение.
O — Output: формат — выгрузка, дашборд, автоотчёт.
P — Priority: как это по срочности относительно других задач.
E — Exceptions: что исключаем, какие риски.
5. Кейсы
📍 Из выгрузки в дашборд
Запрос: «Скинь продажи по регионам за прошлый месяц».
После уточнений: нужен еженедельный мониторинг + доступ для 3 отделов → сделали дашборд в Tableau, экономим 15 часов в месяц.
📍 Уточнение спасло от спама мёртвым клиентам
Запрос: «Клиенты без покупок 6+ месяцев».
После уточнений: добавили фильтр “открывал рассылки за 3 месяца” → в кампанию попали только живые пользователи.
6. Когда не уточняешь
• Размытые термины («активный клиент» = разные цифры у разных команд).
• Неверный период (30 дней ≠ календарный месяц).
• Игнор контекста (миллиард строк вместо нужной агрегации).
• Срыв приоритетов (взялся за «срочную» задачу и завалил реально важную).
7. Как прокачать навык
• Не бойся казаться медленным — страшнее сделать бесполезно.
• Используй чек-лист вопросов.
• Переформулируй задачу и жди подтверждения.
• Веди базу определений метрик.
8. Пример живого диалога
— Скинь продажи по Москве за прошлый квартал.
— А для чего? Отчёт или анализ трендов?
— Для презентации руководству.
— Сравнение с прошлым кварталом или и с прошлым годом?
— И с годом тоже.
— Таблица или график?
— График.
Запрос → Excel
Результат → график с трендом и комментариями прямо в презентации.
Попробуй: на каждый новый запрос — задай хотя бы 3 уточняющих вопроса.
Посмотри, сколько переделок удастся избежать.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
💸 Поддержать канал
👉 Senior Data Analyst | #soft #product
🔥14🤝1
📌 Теория: Теория вероятностей на пальцах — что должен знать каждый аналитик
Вся аналитика строится на вероятностях — даже если вы не замечаете этого.
Ниже — ключевые концепты с примерами на Python, которые пригодятся в SQL-запросах, A/B-тестах, продуктовых метриках и ML-моделях.
Краткие выводы:
P(A|B) — используется в пользовательских воронках и последовательном поведении
Байес — основа спам-фильтров, предиктивных моделей и рекомендаций
Сложение вероятностей — важно для уникальных пользователей и перекрывающихся действий
Binom/Norm/Poisson — фундамент A/B-тестов, ML и оценки редких событий
Совет
Изучайте вероятность через реальные задачи: A/B-тесты, email-рассылки, CTR, прогнозирование поведения. Тогда теория «зайдет» легко и навсегда.
Эта база позволяет перейти от описательной аналитики к вероятностной. Вернись к ней, когда будешь считать конверсии, воронки или доверительные интервалы.
💸 Поддержать канал
👉 Senior Data Analyst | #python
Вся аналитика строится на вероятностях — даже если вы не замечаете этого.
Ниже — ключевые концепты с примерами на Python, которые пригодятся в SQL-запросах, A/B-тестах, продуктовых метриках и ML-моделях.
Краткие выводы:
P(A|B) — используется в пользовательских воронках и последовательном поведении
Байес — основа спам-фильтров, предиктивных моделей и рекомендаций
Сложение вероятностей — важно для уникальных пользователей и перекрывающихся действий
Binom/Norm/Poisson — фундамент A/B-тестов, ML и оценки редких событий
Совет
Изучайте вероятность через реальные задачи: A/B-тесты, email-рассылки, CTR, прогнозирование поведения. Тогда теория «зайдет» легко и навсегда.
Эта база позволяет перейти от описательной аналитики к вероятностной. Вернись к ней, когда будешь считать конверсии, воронки или доверительные интервалы.
💸 Поддержать канал
👉 Senior Data Analyst | #python
1🤝9❤1🔥1
◾️ Нормализация vs Денормализация
Зачем вообще спорить про это?
Потому что в нормализации удобно жить данным, а в денормализации — людям.
Если совсем по-простому: нормализация спасает от бардака и дублей, денормализация — от длинных и медленных запросов. В нормализованном мире удобно жить данным, в денормализованном — людям. В зрелых системах нужны оба подхода — просто в разных слоях.
Нормализация
Денормализация
В реальности не «или-или».
👉 Senior Data Analyst | #sql #dwh
Зачем вообще спорить про это?
Потому что в нормализации удобно жить данным, а в денормализации — людям.
Если совсем по-простому: нормализация спасает от бардака и дублей, денормализация — от длинных и медленных запросов. В нормализованном мире удобно жить данным, в денормализованном — людям. В зрелых системах нужны оба подхода — просто в разных слоях.
Нормализация
Каждая таблица про одну сущность, связи через ключи.
• Целостность: «Москва» и «Moscow» не заведутся параллельно.
• Обновления — в одном месте.
– Аналитика требует JOIN’ов (иногда 5–6 подряд).
👉 Лучший выбор для OLTP (CRM, биллинг, ERP).
Денормализация
Широкие таблицы: всё нужное уже под рукой.
• Запросы проще и быстрее.
• Отлично для BI и ML.
– Дублирование, сложнее обновлять.
👉 Оптимальна для OLAP (DWH, витрины).
В реальности не «или-или».
Архитектура обычно такая:
• Staging → сырые данные,
• Core → нормализованное ядро,
• Marts → денормализованные витрины.
👉 Senior Data Analyst | #sql #dwh
👍6
🔹 Что такое нормализация
Нормализация — это способ организовать таблицы так, чтобы:
• не дублировать одну и ту же информацию в десяти местах;
• сохранять целостность (одно изменение — одно место);
• избежать аномалий при вставках/обновлениях/удалениях.
Идея простая: каждая таблица про одну сущность, связи — через ключи.
Примеры:
• Пользователь и его регион лежат в разных таблицах и связываются по ключу.
• Таблица заказов хранит
Когда это хорошо:
• Переименовали регион — обновили одну строку в справочнике.
• Нет «Москва» и «Moscow» одновременно.
• Отлично работает для систем с большим количеством транзакций (CRM, ERP, биллинг).
Минусы:
• Аналитика почти всегда = JOINы (иногда 5–6 подряд).
• Запросы тяжелее и менее читаемы.
• На больших объёмах JOINы становятся бутылочным горлышком.
🔹 Нормальные формы
Обычно под «нормализовали» имеют в виду до 3NF. Но давай по ступенькам:
1NF — Первая нормальная форма
Анти-пример: phones = '123, 456, 789'.
Правильно: выносим телефоны в отдельную таблицу user_phones.
2NF — Вторая нормальная форма
Анти-пример: таблица с ключом (
3NF — Третья нормальная форма
Анти-пример:
BCNF (Boyce–Codd)
Что это даёт:
🔹 Где нормализация рулит, а где — мешает
Нормализация — это способ организовать таблицы так, чтобы:
• не дублировать одну и ту же информацию в десяти местах;
• сохранять целостность (одно изменение — одно место);
• избежать аномалий при вставках/обновлениях/удалениях.
Идея простая: каждая таблица про одну сущность, связи — через ключи.
Примеры:
• Пользователь и его регион лежат в разных таблицах и связываются по ключу.
• Таблица заказов хранит
customer_id
, а не дублирует имя клиента и регион.Когда это хорошо:
• Переименовали регион — обновили одну строку в справочнике.
• Нет «Москва» и «Moscow» одновременно.
• Отлично работает для систем с большим количеством транзакций (CRM, ERP, биллинг).
Минусы:
• Аналитика почти всегда = JOINы (иногда 5–6 подряд).
• Запросы тяжелее и менее читаемы.
• На больших объёмах JOINы становятся бутылочным горлышком.
Вывод: нормализация — идеальна для OLTP: важна целостность, а не скорость многотабличной аналитики.
🔹 Нормальные формы
Обычно под «нормализовали» имеют в виду до 3NF. Но давай по ступенькам:
1NF — Первая нормальная форма
• Колонки атомарны: одно поле — одно значение, без списков и вложенных структур.
• Строки уникальны (ключ есть).
Анти-пример: phones = '123, 456, 789'.
Правильно: выносим телефоны в отдельную таблицу user_phones.
2NF — Вторая нормальная форма
• Выполнена 1NF.
• Любой неключевой атрибут зависит от всего составного ключа, а не от части.
Анти-пример: таблица с ключом (
student_id, course_id
) и колонкой student_name
. Имя зависит только от student_id
→ вон в students
.3NF — Третья нормальная форма
• Выполнена 2NF.
• Нет транзитивных зависимостей: атрибуты зависят только от ключа, а не друг от друга.
Анти-пример:
employees(emp_id, dept_id, dept_name)
.dept_name
зависит от dept_id
, а не от emp_id
→ отделы в отдельную таблицу.BCNF (Boyce–Codd)
• Строже 3NF: все функциональные зависимости — от суперключей.
• В проде редко «доводят до идеала», но полезно понимать принцип.
Что это даёт:
• 1NF — атомарность, без каши в полях.
• 2NF — нет дублей из-за составных ключей.
• 3NF — модульность: меняем в одном месте.
• BCNF — теория на страже порядка, на практике — точечно.
🔹 Где нормализация рулит, а где — мешает
• OLTP (частые изменения, транзакции, строгая целостность) — цель номер один: качество и точность.
• DWH ядро часто делают ещё более нормализованным (Data Vault), чтобы аккуратно хранить историю и связи.
• BI-витринах чистая 3NF не нужна — здесь важнее удобство и скорость чтения.
👍4❤1
🔹 Что такое денормализация
Денормализация — осознанное «расплющивание» схемы, когда мы собираем широкие таблицы с готовыми атрибутами, чтобы:
• писать короткие запросы;
• быстро строить графики/дашборды;
• кормить ML-модели без десяти JOINов.
Примеры:
• В таблице заказов уже есть имя клиента и регион (а не только
• Факт продаж содержит сразу измерения: продукт, категория, канал, дата, регион.
Плюсы:
• Просто и быстро читать.
• BI-инструменты «летят».
• Идеально для ML-фичей: одна широкая таблица — много признаков.
Минусы:
• Дублирование (Москва в миллионе строк).
• Сложнее обновлять: поменялся регион → перестраиваем витрину.
• Несогласованность версий, если у команд свои пайплайны.
🔹 не «или-или», а «и-и»: слоистая архитектура
🔹 Немного про историчность (SCD)
Когда данные меняются «понемногу и не каждый день», всплывает тема SCD.
• В ядре (нормализованном) удобно хранить Type 2: отдельные записи с
• В витрине чаще:
- либо «замораживаем» срез (snapshot) на нужную дату
- либо храним только актуальную версию.
Практический вывод: глубокая история → в нормализованное ядро; оперативная аналитика и отчёты «на сегодня» → в денормализованные витрины.
🔹 Кейсы аналитики
Кейс 1. Финансовый отчёт «как было на дату»
Кейс 2. BI-дашборд «Продажи по регионам и категориям»
Кейс 3. ML-признаки для модели оттока
🔹 Подводные камни, о которых стоит помнить
• Несогласованные версии. Разные команды денормализуют по-своему → несколько «истин».
Решение: единый Core и централизованная сборка витрин.
• Обновления. В нормализации одно изменение = один апдейт; в денормализации иногда нужен полный пересчёт витрины.
• Производительность. JOINы на больших таблицах медленные, но и «wide» разрастаются.
Баланс зависит от задач и платформы (в облаках диски дешевле CPU — это влияет на дизайн).
• Определения метрик. «Активный клиент», «заказ», «выручка» — без чётких договорённостей цифры расползутся.
Решение: словарь метрик и контракты данных.
🔹 Архитектурные паттерны
• 3NF: чисто, предсказуемо, удобно для транзакций и истории, тяжеловато для BI.
• Data Vault: хабы-линки-сателлиты; гибкая историзация и инкрементальные загрузки; отличное ядро для DWH.
• Star Schema (звезда): факт + денормализованные измерения; любимая схема BI.
• Snowflake: «звезда», у которой часть измерений слегка нормализована — компромисс между чистотой и простотой.
• Wide Table: полностью «плоская» витрина; быстро для чтения и ML, но тяжёлая в обслуживании.
Услал читать? вот итог в одном месте
Итог в одном абзаце 👇
Нормализация делает данные надёжными и историзуемыми. Денормализация делает ответы быстрыми и удобными.
Зрелая архитектура — это staging → core → marts, где ядро отвечает за «правду», а витрины — за скорость.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
Денормализация — осознанное «расплющивание» схемы, когда мы собираем широкие таблицы с готовыми атрибутами, чтобы:
• писать короткие запросы;
• быстро строить графики/дашборды;
• кормить ML-модели без десяти JOINов.
Примеры:
• В таблице заказов уже есть имя клиента и регион (а не только
customer_id
).• Факт продаж содержит сразу измерения: продукт, категория, канал, дата, регион.
Плюсы:
• Просто и быстро читать.
• BI-инструменты «летят».
• Идеально для ML-фичей: одна широкая таблица — много признаков.
Минусы:
• Дублирование (Москва в миллионе строк).
• Сложнее обновлять: поменялся регион → перестраиваем витрину.
• Несогласованность версий, если у команд свои пайплайны.
Вывод: денормализация — выбор для OLAP: приоритет скорость чтения и удобство потребителей.
🔹 не «или-или», а «и-и»: слоистая архитектура
В реальности:
• Staging (сырое): тащим из источников почти как есть. Тут возможны дубли, разные форматы — задача не потерять информацию.
• Core (ядро): нормализованная модель (3NF или Data Vault) — единый словарь, «истинная версия», аккуратная историзация.
• Marts (витрины): денормализованные таблицы под конкретные вопросы бизнеса (звезда, снежинка, wide-table).
Логика проста: ядро обеспечивает качество/историю, витрины — удобство/скорость.
🔹 Немного про историчность (SCD)
Когда данные меняются «понемногу и не каждый день», всплывает тема SCD.
• В ядре (нормализованном) удобно хранить Type 2: отдельные записи с
valid_from / valid_to
. Историю поднять — не проблема.• В витрине чаще:
- либо «замораживаем» срез (snapshot) на нужную дату
- либо храним только актуальную версию.
Практический вывод: глубокая история → в нормализованное ядро; оперативная аналитика и отчёты «на сегодня» → в денормализованные витрины.
🔹 Кейсы аналитики
Кейс 1. Финансовый отчёт «как было на дату»
Финансам важно восстановить картину прошлого месяца.
• Нормализация позволяет собрать справочники в состоянии на дату.
• Денормализованная витрина даёт быструю выгрузку без JOINов.
Лучшее из двух миров: ядро с историей + витрина под отчёт.
Кейс 2. BI-дашборд «Продажи по регионам и категориям»
• Нормализованная схема → 5 JOINов и неочевидные ошибки в фильтрах.
• Денормализованная витрина → одна агрегация из «широкой» таблицы.
Для BI всегда готовим витрину, а не заставляем дашборд «склеивать» полмира.
Кейс 3. ML-признаки для модели оттока
• Из ядра берём историю профиля и действий.
• Во «wide»-таблице собираем признаки: сумма покупок, средний чек, частота, давность событий.
Модель учится на денормализованной таблице, но питается из нормализованной истории.
🔹 Подводные камни, о которых стоит помнить
• Несогласованные версии. Разные команды денормализуют по-своему → несколько «истин».
Решение: единый Core и централизованная сборка витрин.
• Обновления. В нормализации одно изменение = один апдейт; в денормализации иногда нужен полный пересчёт витрины.
• Производительность. JOINы на больших таблицах медленные, но и «wide» разрастаются.
Баланс зависит от задач и платформы (в облаках диски дешевле CPU — это влияет на дизайн).
• Определения метрик. «Активный клиент», «заказ», «выручка» — без чётких договорённостей цифры расползутся.
Решение: словарь метрик и контракты данных.
🔹 Архитектурные паттерны
• 3NF: чисто, предсказуемо, удобно для транзакций и истории, тяжеловато для BI.
• Data Vault: хабы-линки-сателлиты; гибкая историзация и инкрементальные загрузки; отличное ядро для DWH.
• Star Schema (звезда): факт + денормализованные измерения; любимая схема BI.
• Snowflake: «звезда», у которой часть измерений слегка нормализована — компромисс между чистотой и простотой.
• Wide Table: полностью «плоская» витрина; быстро для чтения и ML, но тяжёлая в обслуживании.
Услал читать? вот итог в одном месте
Итог в одном абзаце 👇
Нормализация делает данные надёжными и историзуемыми. Денормализация делает ответы быстрыми и удобными.
Зрелая архитектура — это staging → core → marts, где ядро отвечает за «правду», а витрины — за скорость.
💥 Как тебе ?
🔥 — узнал(а) что-то новое
🤝 — темы хорошо знакомы
🔥8❤2👍2👌1🤝1
Библиотеки ML, которые должен знать каждый аналитик
🔹 Scikit-learn
🔹 Statsmodels
🔹 XGBoost
Вывод:
Эти 3 библиотеки закрывают 80–90% задач, с которыми сталкивается аналитик данных.
💸 Поддержать канал
👉 Senior Data Analyst | #ml #python
🔹 Scikit-learn
твой первый помощник в ML. Здесь всё: от предобработки данных и обучения моделей до расчёта метрик. Подходит для MVP, A/B-тестов, скоринга, быстрых экспериментов.
🔹 Statsmodels
если важна статистическая интерпретация. Поддерживает t-тесты, ANOVA, регрессии с p-value и доверительными интервалами. Особенно полезен, когда модель нужно объяснить заказчику или прописать в отчёте.
🔹 XGBoost
лидер по точности. Работает с табличными данными, отлично справляется с задачами прогнозирования и классификации. Подходит для оценки LTV, churn, scoring-моделей. Используется в продакшн-решениях.
Вывод:
Эти 3 библиотеки закрывают 80–90% задач, с которыми сталкивается аналитик данных.
💸 Поддержать канал
👉 Senior Data Analyst | #ml #python
🔥6❤1👍1
PySpark — это не «костыль, чтобы ноутбук не падал».
Когда данных становится слишком много, ноутбук начинает страдать.
pandas не виноват — он просто не для этого.
Если ты аналитик, который хочет вырасти за пределы локальной машины и «Excel-ментальности» — PySpark открывает тебе дверь в инженерный мир, при этом не отнимая любимую гибкость Python.
🚀 Попробуй: запусти Spark локально и прогон свой pandas-пайплайн.
Увидишь, что «big data» не страшный зверь, а нормальный рабочий процесс.
💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
Когда данных становится слишком много, ноутбук начинает страдать.
pandas не виноват — он просто не для этого.
PySpark умеет: делить данные, крутить их в кластере и делать так, что у тебя остаётся пандасовая простота, но в масштабе.
Если ты аналитик, который хочет вырасти за пределы локальной машины и «Excel-ментальности» — PySpark открывает тебе дверь в инженерный мир, при этом не отнимая любимую гибкость Python.
🚀 Попробуй: запусти Spark локально и прогон свой pandas-пайплайн.
Увидишь, что «big data» не страшный зверь, а нормальный рабочий процесс.
💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
👍3🔥2👏1👌1
📌 Почему аналитикам пора дружить с PySpark
Когда твои данные перестают влезать в память ноутбука, pandas превращается в чемодан без ручки.
Он хорош для прототипов и быстрых исследований, но не создан для масштаба enterprise.
Здесь на сцену выходит PySpark — не как «ещё одна библиотека», а как партнёр по данным.
▫️ PySpark = распределённое мышление
Spark — это не «ускоренный pandas».
Это система, которая делит данные на части, раскидывает их по узлам кластера и работает параллельно.
Главное отличие: Spark ленив.
Что это даёт аналитику?
• обработку терабайтов без упора в память;
• масштабирование от ноутбука до сотен узлов;
• устойчивость к сбоям — задачи переисполняются сами;
• DataFrame API, где удобно как в pandas, но возможностей — на порядок больше.
▫️Аналитика с инженерным акцентом
Представь e-commerce: заказы, логи, CRM, транзакции.
В pandas — постоянная боль. В PySpark — рабочая рутина:
• читаешь данные распределённо;
• приводишь к единой схеме;
• считаешь метрики через оконные функции;
• сохраняешь в Parquet или Delta Lake.
В итоге у тебя не скрипт «на удачу», а DAG, который можно запускать по расписанию и воспроизводить снова и снова.
▫️ Как мыслить в PySpark
• Схема данных явно > чем автоинференс. Иначе арифметика может рухнуть.
• Партиционирование — искусство. От него зависит скорость.
• UDF — крайний случай. Встроенные функции почти всегда быстрее.
• Кэшировать можно, но осторожно. Экономит время, но ест память.
▫️ Когнитивный сдвиг
Если pandas — это «данные прямо здесь и сейчас»,
то PySpark — это про описание желаемого результата.
Ты перестаёшь думать «как обработать каждую строку» и начинаешь описывать:
Это требует времени на перестройку мышления, но открывает масштаб и стабильность.
▫️ PySpark в стеке
▫️Что получает бизнес
• повторяемость без ручных выгрузок;
• масштабируемость без переписывания кода;
• тестируемость на сэмплах локально;
• надёжность и устойчивость по умолчанию.
▫️ Подводные камни
• Очень широкие таблицы (1000+ колонок).
• Перекосы при join’ах (skewed data).
• Эволюция схемы не всегда прозрачна.
• Часовые пояса → неожиданные баги с датами.
▫️ Итог: pandas — отличное начало. Но если твои данные растут быстрее, чем память ноутбука, PySpark перестаёт быть выбором. Это необходимость.
💥 Как тебе инструмент?
🔥 — что-то новое для меня
🤝 — хорошо знаком
💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
Когда твои данные перестают влезать в память ноутбука, pandas превращается в чемодан без ручки.
Он хорош для прототипов и быстрых исследований, но не создан для масштаба enterprise.
Здесь на сцену выходит PySpark — не как «ещё одна библиотека», а как партнёр по данным.
▫️ PySpark = распределённое мышление
Spark — это не «ускоренный pandas».
Это система, которая делит данные на части, раскидывает их по узлам кластера и работает параллельно.
Главное отличие: Spark ленив.
Ты пишешь фильтры и группировки, а он лишь строит план (DAG).
Считается всё только тогда, когда ты попросишь результат.
Что это даёт аналитику?
• обработку терабайтов без упора в память;
• масштабирование от ноутбука до сотен узлов;
• устойчивость к сбоям — задачи переисполняются сами;
• DataFrame API, где удобно как в pandas, но возможностей — на порядок больше.
▫️Аналитика с инженерным акцентом
Представь e-commerce: заказы, логи, CRM, транзакции.
В pandas — постоянная боль. В PySpark — рабочая рутина:
• читаешь данные распределённо;
• приводишь к единой схеме;
• считаешь метрики через оконные функции;
• сохраняешь в Parquet или Delta Lake.
В итоге у тебя не скрипт «на удачу», а DAG, который можно запускать по расписанию и воспроизводить снова и снова.
▫️ Как мыслить в PySpark
• Схема данных явно > чем автоинференс. Иначе арифметика может рухнуть.
• Партиционирование — искусство. От него зависит скорость.
• UDF — крайний случай. Встроенные функции почти всегда быстрее.
• Кэшировать можно, но осторожно. Экономит время, но ест память.
▫️ Когнитивный сдвиг
Если pandas — это «данные прямо здесь и сейчас»,
то PySpark — это про описание желаемого результата.
Ты перестаёшь думать «как обработать каждую строку» и начинаешь описывать:
«Как должна измениться вся таблица».
Это требует времени на перестройку мышления, но открывает масштаб и стабильность.
▫️ PySpark в стеке
Airflow — оркестрация пайплайнов.
MLflow — хранение и воспроизводимость фичей.
Delta Lake — версияция и транзакции.
ClickHouse — real-time аналитика.
Dash/Plotly — визуализация прямо с кластера.
▫️Что получает бизнес
• повторяемость без ручных выгрузок;
• масштабируемость без переписывания кода;
• тестируемость на сэмплах локально;
• надёжность и устойчивость по умолчанию.
▫️ Подводные камни
• Очень широкие таблицы (1000+ колонок).
• Перекосы при join’ах (skewed data).
• Эволюция схемы не всегда прозрачна.
• Часовые пояса → неожиданные баги с датами.
▫️ Итог: pandas — отличное начало. Но если твои данные растут быстрее, чем память ноутбука, PySpark перестаёт быть выбором. Это необходимость.
💥 Как тебе инструмент?
🔥 — что-то новое для меня
🤝 — хорошо знаком
💸 Поддержать канал
👉 Senior Data Analyst | #pyspark #python
🔥10
This media is not supported in your browser
VIEW IN TELEGRAM
sweetviz — это библиотека для автоматического EDA, которая показывает, что с вашими данными не так (или наоборот — так) буквально за 1 минуту.
Работает с pandas, быстро генерирует отчёт в HTML и покрывает: null’ы, выбросы, распределения, корреляции, сравнение выборок.
Подходит для:
Не надо вручную писать десятки .groupby() и sns.histplot().
Особенно удобно, если ты middle и времени мало — sweetviz берёт рутину на себя.
📎 GitHub
💸 Поддержать канал
👉 Senior Data Analyst | #Python
Работает с pandas, быстро генерирует отчёт в HTML и покрывает: null’ы, выбросы, распределения, корреляции, сравнение выборок.
Подходит для:
— быстрого анализа выгрузки
— A/B-сравнений
— подготовки ML-фичей
— объяснений для менеджеров
Не надо вручную писать десятки .groupby() и sns.histplot().
Особенно удобно, если ты middle и времени мало — sweetviz берёт рутину на себя.
📎 GitHub
💸 Поддержать канал
👉 Senior Data Analyst | #Python
🔥10
Чуть подробнее о том, что такое Sweetviz
Когда ты впервые сталкиваешься с новым датасетом, главное — быстро понять, что внутри. Не копаться вручную в сотнях строк и колонок, а увидеть ключевые сигналы: где пропуски, где перекосы, где потенциальные ловушки.
И вот тут появляется Sweetviz.
Один импорт — и ты уже понимаешь данные
Sweetviz — инструмент первого взгляда. Он не строит модели и не убирает шум, зато сразу показывает, с чем ты имеешь дело. И делает это красиво.
Загрузил датасет — получил наглядный отчёт:
всё это — в одном HTML-файле, который можно скинуть в рабочий чат или показать заказчику.
Когда особенно полезен Sweetviz:
Главное преимущество Sweetviz — он экономит твоё внимание.
📎 GitHub
💸 Поддержать канал
👉 Senior Data Analyst | #Python
Когда ты впервые сталкиваешься с новым датасетом, главное — быстро понять, что внутри. Не копаться вручную в сотнях строк и колонок, а увидеть ключевые сигналы: где пропуски, где перекосы, где потенциальные ловушки.
И вот тут появляется Sweetviz.
Один импорт — и ты уже понимаешь данные
Sweetviz — инструмент первого взгляда. Он не строит модели и не убирает шум, зато сразу показывает, с чем ты имеешь дело. И делает это красиво.
Загрузил датасет — получил наглядный отчёт:
где пропуски,
где перекосы,
где можно легко ошибиться.
всё это — в одном HTML-файле, который можно скинуть в рабочий чат или показать заказчику.
Когда особенно полезен Sweetviz:
Новый датасет — нужно быстро понять, с чем работаешь.
A/B-тест — нужен sanity check, прежде чем углубляться.
Начинаешь писать ML-пайплайн — хочется сразу вычистить мусор.
Главное преимущество Sweetviz — он экономит твоё внимание.
📎 GitHub
💸 Поддержать канал
👉 Senior Data Analyst | #Python
👍5🔥2
Разбор: Почему Sweetviz = твой аналитический напарник
Когда не хочется тратить вечер на
Он превращает DataFrame в готовый EDA-отчёт — быстрый, красивый и понятный даже менеджеру.
▫️Что умеет Sweetviz
• показывает распределения и пропуски
• ищет корреляции и выбросы
• сравнивает подгруппы (идеально для A/B)
• оценивает важность фичей при заданном target
▫️Почему это удобно в коде
• функции чётко разделены (
• Pathlib вместо строк → кроссплатформенно и чище;
• встроенные проверки колонок → меньше боли с KeyError.
▫️Где применять
• sanity-check выгрузки от коллег
• быстрый A/B-анализ без десятка
• разведка перед ML — видно шум, дисбаланс и сильные корреляции
• автогенерация отчётов для дашбордов
▫️Ограничения
• медленный на >100k строк
• мало гибкости (нет кастомных агрегаций)
• HTML-отчёт нельзя встроить в Streamlit/Dash напрямую
• нет JSON-выгрузки → отчёт только «для глаз»
🤝 Вывод
Sweetviz — это как Excel-аналитик, у которого никогда не устают глаза.
Он не заменит глубокий анализ, но спасает, когда нужно быстро понять:
«А вообще, с какими данными я работаю?»
Импортируй sweetviz и забудь про
💥 Как тебе Sweetviz?
🔥 — активно пользуюсь
🤔 — слышал(а), но не пробовал(а)
👍 — узнал(а) о нём впервые
Когда не хочется тратить вечер на
df.groupby().agg()
и бесконечные sns.histplot()
, на помощь приходит Sweetviz.Он превращает DataFrame в готовый EDA-отчёт — быстрый, красивый и понятный даже менеджеру.
▫️Что умеет Sweetviz
• показывает распределения и пропуски
• ищет корреляции и выбросы
• сравнивает подгруппы (идеально для A/B)
• оценивает важность фичей при заданном target
Всё это сразу в HTML-отчёте: открыл в браузере и смотришь интерактив.
▫️Почему это удобно в коде
• функции чётко разделены (
load_data
, generate_full_report
, generate_group_comparison
) → проще тестировать и переиспользовать;• Pathlib вместо строк → кроссплатформенно и чище;
• встроенные проверки колонок → меньше боли с KeyError.
▫️Где применять
• sanity-check выгрузки от коллег
• быстрый A/B-анализ без десятка
groupby
• разведка перед ML — видно шум, дисбаланс и сильные корреляции
• автогенерация отчётов для дашбордов
▫️Ограничения
• медленный на >100k строк
• мало гибкости (нет кастомных агрегаций)
• HTML-отчёт нельзя встроить в Streamlit/Dash напрямую
• нет JSON-выгрузки → отчёт только «для глаз»
🤝 Вывод
Sweetviz — это как Excel-аналитик, у которого никогда не устают глаза.
Он не заменит глубокий анализ, но спасает, когда нужно быстро понять:
«А вообще, с какими данными я работаю?»
Импортируй sweetviz и забудь про
sns.pairplot()
.💥 Как тебе Sweetviz?
🔥 — активно пользуюсь
🤔 — слышал(а), но не пробовал(а)
👍 — узнал(а) о нём впервые
👍4🤔4
🧠 Python для аналитиков: list comprehensions и полезные операторы
Это третья серия модуля 3 — и она про то, как писать Python: компактно, читаемо и в духе «питоничности».
кейс с CSV
объясняем
практика с # TODO:
20+ примеров с комментариями:
полный обзор встроенных операторов:
вложенные и многоуровневые конструкции:
❤️ И да, поставь реакцию за старание
💾 Скачать серию
💸 Поддержать канал
👉 Senior Data Analyst #python #модуль_03 #серия_03
Это третья серия модуля 3 — и она про то, как писать Python: компактно, читаемо и в духе «питоничности».
кейс с CSV
→ агрегируем продажи и выводим топ-5 товаров
объясняем
→ синтаксис list comprehension
практика с # TODO:
→ уникальные слова, таблица умножения, сортировка студентов
20+ примеров с комментариями:
→ от фильтрации чисел до генерации таблиц
полный обзор встроенных операторов:
→ any, all, zip, enumerate, sorted, map, filter
вложенные и многоуровневые конструкции:
→ матрицы, flatten, словари и множества
❤️ И да, поставь реакцию за старание
💾 Скачать серию
💸 Поддержать канал
👉 Senior Data Analyst #python #модуль_03 #серия_03
❤11
❓ Почему COUNT(*) может врать
На первый взгляд, COUNT(*) — надёжный. Он ведь просто считает строки, верно?
Где чаще всего обманывает:
▫️Дубликаты в источниках. ETL сломался — order_id задублировался, а COUNT(*) считает всё подряд.
▫️JOIN-размножение. Соединил пользователей с заказами и доставками? Один заказ превращается в несколько строк.
▫️Путаница в сущностях. Нам нужно посчитать «пользователей» или «заказы», а на деле считаем просто строки.
Как мыслить правильно:
▫️сначала определить что именно считаем (строки, уникальные заказы, пользователей);
▫️COUNT(DISTINCT) спасает, но стоит дорого;
▫️предагрегация перед JOIN почти всегда лучше;
▫️чистка источников = меньше дублей на входе.
В бою:
Я всегда отношусь к
💸 Поддержать канал
👉 Senior Data Analyst | #sql
На первый взгляд, COUNT(*) — надёжный. Он ведь просто считает строки, верно?
Но тут и ловушка: он считает всё, что попало в результат, а не то, что мы называем бизнес-сущностью.
Где чаще всего обманывает:
▫️Дубликаты в источниках. ETL сломался — order_id задублировался, а COUNT(*) считает всё подряд.
▫️JOIN-размножение. Соединил пользователей с заказами и доставками? Один заказ превращается в несколько строк.
▫️Путаница в сущностях. Нам нужно посчитать «пользователей» или «заказы», а на деле считаем просто строки.
Как мыслить правильно:
▫️сначала определить что именно считаем (строки, уникальные заказы, пользователей);
▫️COUNT(DISTINCT) спасает, но стоит дорого;
▫️предагрегация перед JOIN почти всегда лучше;
▫️чистка источников = меньше дублей на входе.
В бою:
Я всегда отношусь к
COUNT(*)
с подозрением.На ревью самый частый вопрос: «А не размножает ли JOIN строки?»
Если да — COUNT(*) почти наверняка врёт.
💸 Поддержать канал
👉 Senior Data Analyst | #sql
👍6🤝2