Друзья, привет!
Ну что, как понять, что новогодний отдых удался, а вы готовы снова вливаться в рабочий ритм? У меня вчерашний день получился довольно… необычным :)
А дальше была эпичная битва с паролем от рабочего компа, которая длилась минут 30. Итог — пароль сдался, а я стал чуточку счастливее.
Если с вами вчера тоже приключилось что-то забавное — делитесь, будет интересно почитать!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3😁3🤓2❤1
Вы когда-нибудь задумывались, как ваши фотки с отпуска попадают в облако и остаются там навечно, даже если вы забыли пароль от аккаунта? Это всё благодаря распределённым системам.
На первый взгляд кажется, что данные просто «улетели в облако», но на самом деле их обрабатывают сотни серверов, работающих вместе, как хорошо слаженный оркестр — только вместо музыки они гоняют петабайты данных.
⚒️ Для Data Engineer распределённые системы — это must have, потому что они строят решения, которые должны работать на больших объёмах данных. Нельзя просто взять один сервер и заставить его хранить терабайты — он рано или поздно сгорит, как старый утюг. Поэтому данные хранятся на множестве машин. Обработка тоже должна быть быстрой — миллионы записей одним SQL-запросом за пару секунд обычный сервер не осилит, здесь на помощь приходят Spark и Hadoop. И, конечно, отказоустойчивость: если один сервер упал, система должна продолжить работать, а не напоминать цирк с обвалившимися декорациями. Без распределённых систем ни крупные ETL-процессы, ни современные аналитические платформы попросту не взлетят.
🛤️ Для каких направлений это важно?
📚 С чего начать изучение?
Apache Kafka — основа потоковой обработки данных.
Apache Spark — распределённая обработка данных в кластере.
HDFS / S3 — распределённые файловые хранилища.
Ведь кто строит мосты между миром данных и бизнесом? Data Engineers. А значит, без распределённых систем — никуда.
Это я так плавно вас подвожу к Hadoop и Spark
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤4👍3👏2
#путь_de
Когда-то в 2021 году ✨ мне довелось пройти курс по Hadoop от Сбера. Тогда я ещё не имел практического опыта ни с Python, ни с распределёнными системами, но внутренне чувствовал: это то, что приведёт меня к интересным проектам в Big Data!
По мере углубления понял, что теоретические знания — это одно, а реальная практика на работе — совсем другое. Когда я перешёл в новую команду и начал работать со Spark, то ощутил тот самый «буст» 🚀, которого так ждал. Теперь, спустя почти год реальной работы, я могу сказать: основы Spark осилить реально, но глубина может быть огромной.
⚙️ Два условных направления Data Engineering
Сегодня часто можно заметить два условных «лагеря» в мире Data Engineering:
1. Инженеры, которые работают на Spark
🔸 Сосредоточены на сборе данных из разных источников (файловые хранилища, потоки, базы).
🔸 Делают первичную или сложную обработку, трансформации, очищают данные, пишут ETL.
🔸 Готовят и загружают результат в DWH или другие системы.
2. Инженеры, которые «живут» в DWH (Greenplum или другое)
🔹 Отвечают за организацию и хранение данных в хранилище.
🔹 Нарезают данные по слоям, строят витрины и оптимизируют запросы.
🔹 Глубоко разбираются в архитектуре MPP/SQL, знают, как распределять и партиционировать таблицы.
⭐️ Почему я выделяю Spark и Greenplum?
🔸 Spark: это фреймворк для распределённых вычислений, который помогает обрабатывать большие объёмы данных. Он гибок и масштабируем, но требует чёткого понимания:
- Как устроена концепция DataFrame, Dataset и RDD.
- Как грамотно настраивать кластеры и оптимизировать job, чтобы не «утонуть» в ресурсах.
- Как работать с разными форматами данных (CSV, Parquet, JSON и т.д.).
🔹 Greenplum: это MPP-хранилище (Massively Parallel Processing), базирующееся на PostgreSQL. Отлично подходит для:
- Хранения больших массивов данных, когда нужно параллелить SQL-запросы.
- Аналитической обработки, построения сложных отчётов и витрин.
- Глубокой работы с SQL, оптимизацией запросов, грамотным распределением данных по сегментам.
✨ Ключевые различия (коротко)
- Фокус: Spark ориентирован на распределённые вычисления и ETL, Greenplum — на хранение и аналитические SQL-запросы.
- Язык: у Spark — это чаще Python/Scala, а у Greenplum — SQL.
- Масштаб: Spark «растёт» под задачу динамично, Greenplum масштабируется за счёт параллельной архитектуры внутри базы.
✅ Требования к знаниям и навыкам
Чтобы уверенно чувствовать себя в Spark, желательно:
- Понимать модель распределённых вычислений (как данные делятся и обрабатываются параллельно).
- Владеть Python/Scala (или Java) на уровне написания, отладки и оптимизации ETL.
- Уметь читать Spark UI, разбираться в метриках выполнения, настраивать драйверы и экзекьюторы.
Чтобы быть спецом в Greenplum (или другом DWH), будет круто:
- Глубоко понимать реляционные модели и SQL.
- Знать принципы MPP: распределение строк по сегментам, партиционирование, индексирование.
- Уметь настраивать и оптимизировать запросы, использовать Explain/Analyze.
✊ Моя мотивация для вас
Если вы только в начале пути или чувствуете недостаток практики: не переживайте! Главное — это желание осваивать новые вещи и постепенно погружаться в детали. От ETL в Spark до построения витрин в Greenplum — всё это огромный мир Data Engineering, где каждый может найти то, что ему нравится, и стать в этом экспертом.
А совместное использование Spark и Greenplum открывает огромные возможности для компании и для вашего профессионального роста. Дерзайте, учитесь, экспериментируйте — пусть большие данные станут вашим катализатором карьерного успеха! ✨🚀
Когда-то в 2021 году ✨ мне довелось пройти курс по Hadoop от Сбера. Тогда я ещё не имел практического опыта ни с Python, ни с распределёнными системами, но внутренне чувствовал: это то, что приведёт меня к интересным проектам в Big Data!
По мере углубления понял, что теоретические знания — это одно, а реальная практика на работе — совсем другое. Когда я перешёл в новую команду и начал работать со Spark, то ощутил тот самый «буст» 🚀, которого так ждал. Теперь, спустя почти год реальной работы, я могу сказать: основы Spark осилить реально, но глубина может быть огромной.
⚙️ Два условных направления Data Engineering
Сегодня часто можно заметить два условных «лагеря» в мире Data Engineering:
1. Инженеры, которые работают на Spark
🔸 Сосредоточены на сборе данных из разных источников (файловые хранилища, потоки, базы).
🔸 Делают первичную или сложную обработку, трансформации, очищают данные, пишут ETL.
🔸 Готовят и загружают результат в DWH или другие системы.
2. Инженеры, которые «живут» в DWH (Greenplum или другое)
🔹 Отвечают за организацию и хранение данных в хранилище.
🔹 Нарезают данные по слоям, строят витрины и оптимизируют запросы.
🔹 Глубоко разбираются в архитектуре MPP/SQL, знают, как распределять и партиционировать таблицы.
⭐️ Почему я выделяю Spark и Greenplum?
🔸 Spark: это фреймворк для распределённых вычислений, который помогает обрабатывать большие объёмы данных. Он гибок и масштабируем, но требует чёткого понимания:
- Как устроена концепция DataFrame, Dataset и RDD.
- Как грамотно настраивать кластеры и оптимизировать job, чтобы не «утонуть» в ресурсах.
- Как работать с разными форматами данных (CSV, Parquet, JSON и т.д.).
🔹 Greenplum: это MPP-хранилище (Massively Parallel Processing), базирующееся на PostgreSQL. Отлично подходит для:
- Хранения больших массивов данных, когда нужно параллелить SQL-запросы.
- Аналитической обработки, построения сложных отчётов и витрин.
- Глубокой работы с SQL, оптимизацией запросов, грамотным распределением данных по сегментам.
✨ Ключевые различия (коротко)
- Фокус: Spark ориентирован на распределённые вычисления и ETL, Greenplum — на хранение и аналитические SQL-запросы.
- Язык: у Spark — это чаще Python/Scala, а у Greenplum — SQL.
- Масштаб: Spark «растёт» под задачу динамично, Greenplum масштабируется за счёт параллельной архитектуры внутри базы.
✅ Требования к знаниям и навыкам
Чтобы уверенно чувствовать себя в Spark, желательно:
- Понимать модель распределённых вычислений (как данные делятся и обрабатываются параллельно).
- Владеть Python/Scala (или Java) на уровне написания, отладки и оптимизации ETL.
- Уметь читать Spark UI, разбираться в метриках выполнения, настраивать драйверы и экзекьюторы.
Чтобы быть спецом в Greenplum (или другом DWH), будет круто:
- Глубоко понимать реляционные модели и SQL.
- Знать принципы MPP: распределение строк по сегментам, партиционирование, индексирование.
- Уметь настраивать и оптимизировать запросы, использовать Explain/Analyze.
✊ Моя мотивация для вас
Если вы только в начале пути или чувствуете недостаток практики: не переживайте! Главное — это желание осваивать новые вещи и постепенно погружаться в детали. От ETL в Spark до построения витрин в Greenplum — всё это огромный мир Data Engineering, где каждый может найти то, что ему нравится, и стать в этом экспертом.
А совместное использование Spark и Greenplum открывает огромные возможности для компании и для вашего профессионального роста. Дерзайте, учитесь, экспериментируйте — пусть большие данные станут вашим катализатором карьерного успеха! ✨🚀
👍20❤9🔥4🤝1
На днях я изрядно порвал шаблон…
Я пишу на Spark SQL довольно давно. Но тут наткнулся на странность: мне нужно было получить конкретную выборку, я уже знал, что приблизительно должно получиться, но оно не получалось!
Где-то пол часа я вообще не мог понять, в чем дело, грешил на неверные JOIN'ы... А потом обнаружил самое банальное: кто-то (я) забыл про скобочки в WHERE-условии. Вот что я написал (внимание на WHERE блок):
То есть condition_3 проверялся независимо от condition_2, и я получал неверные результаты.
Что должно было быть:
Даже смешно как-то стало, когда я это понял 😅
Казалось бы, самая элементарная вещь, но с каждым может случиться: усталость, дедлайны, всякие отвлекающие факторы — и вот уже сидишь и сомневаешься везде и во всём.
Не забудьте поставить скобочки! Или лучше дважды проверьте, что они там, где нужно.
Товарищи мидлы и сеньоры, вы допускаете такие ошибки?🤔
Поделитесь своими “топовыми” ошибками, которые вспоминаются с улыбкой. Ведь даже эксперты — обычные люди, которым свойственно ошибаться. Главное вовремя увидеть и исправить!✨
Я пишу на Spark SQL довольно давно. Но тут наткнулся на странность: мне нужно было получить конкретную выборку, я уже знал, что приблизительно должно получиться, но оно не получалось!
Где-то пол часа я вообще не мог понять, в чем дело, грешил на неверные JOIN'ы... А потом обнаружил самое банальное: кто-то (я) забыл про скобочки в WHERE-условии. Вот что я написал (внимание на WHERE блок):
SELECT * FROM table
WHERE 1=1
AND condition_1
AND condition_2 OR condition_3
То есть condition_3 проверялся независимо от condition_2, и я получал неверные результаты.
Что должно было быть:
SELECT * FROM table
WHERE 1=1
AND condition_1
AND (condition_2 OR condition_3)
Даже смешно как-то стало, когда я это понял 😅
Казалось бы, самая элементарная вещь, но с каждым может случиться: усталость, дедлайны, всякие отвлекающие факторы — и вот уже сидишь и сомневаешься везде и во всём.
Не забудьте поставить скобочки! Или лучше дважды проверьте, что они там, где нужно.
Товарищи мидлы и сеньоры, вы допускаете такие ошибки?
Поделитесь своими “топовыми” ошибками, которые вспоминаются с улыбкой. Ведь даже эксперты — обычные люди, которым свойственно ошибаться. Главное вовремя увидеть и исправить!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23😁8❤4🔥3
#база_знаний
HDFS: архитектура, полезные команды и интересные вопросы.
Блиц материал по этой системе хранения. Если вы работаете не только с БД, но еще и с обработкой больших данных, HDFS остаётся актуальным, даже когда все вокруг говорят про Cloud💭 .
Напоминаю о том:
❓ Как работает HDFS и зачем он нужен
🔒 что такое репликация и отказоустойчивость
💬 а также привожу список интересных вопросов на подумать и изучить
Вероятно попозже сделаю разбор вопросов или какой-нибудь тест для вашей самопроверки. Если интересно, накидайте реакций 😏
HDFS: архитектура, полезные команды и интересные вопросы.
Блиц материал по этой системе хранения. Если вы работаете не только с БД, но еще и с обработкой больших данных, HDFS остаётся актуальным, даже когда все вокруг говорят про Cloud
Напоминаю о том:
Вероятно попозже сделаю разбор вопросов или какой-нибудь тест для вашей самопроверки. Если интересно, накидайте реакций 😏
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥4👌3
#путь_DE
✏️ Не так давно я писал про культуру разработки и ведения Git.
На работе я использовал Bitbucket для хранения кода релиза, сейчас его же для кода витрин и view, а дома для пет проектов и даже репозитория канала использую GitHub.
😮 Но тут на прошлом спринте я впервые столкнулся с моим первым настоящим code review от моего лида. Это выглядело довольно занимательно и интригующе. Я понимаю, что неоптимальный код должен быть отловлен еще до стадии push в репо. И когда я получил обратно свой код с 20 комментами, то словил двоякое ощущение:
1️⃣ у меня много ошибок, как я так много накосячил, это все увидели. То есть это не конечный результат в виде parquet или любого другого файла, а именно логика ETL с моим стилем кода.
2️⃣ ощущение интереса и роста, поскольку более опытные DE прямо указывает места, которые можно подтюнить здесь и сейчас.
На фикс моего pull request я потратил 2 дня, не без помощи коллеги. Но столкнуться и разобраться с этим было довольно здорово.
И тут пришел еще один инсайт: если у вас есть возможность на проекте, после разработки кидайте ваш код не в файлы локально, а в репо (командное или личное).
Это даст вам несколько преимуществ:
🔹 Вы будите получать опыт разработки и ведения проекта в git по всем канонам. То есть не затрагивая master часть приложения / БД / ETL. Разработка новой фичи / витрины / скрипта будет происходить у вас в новой ветке, а выкат этого в master будет безболезненным с code review.
🔹 Коллеги в любой момент смогут обратиться к вашему коду без вас. Удобно, поскольку совсем недавно я разработал логику для нескольких view, которые отдают данные для BI, и хранил скрипты локально. Конечно, можно посмотреть DDL в БД, но лучше иметь человеческий код под рукой.
🔹 на многих проектах нужен опыт с Git (или аналогами), а тут у вас уже будет набита рука на базовых и необходимых действиях с ним.
😠 Фатальный кейс - если кто-то дропнет (случайно) эти view, а код их создания локально, то тут можно понервничать (со мной и это было 👀 )
На работе я использовал Bitbucket для хранения кода релиза, сейчас его же для кода витрин и view, а дома для пет проектов и даже репозитория канала использую GitHub.
На фикс моего pull request я потратил 2 дня, не без помощи коллеги. Но столкнуться и разобраться с этим было довольно здорово.
И тут пришел еще один инсайт: если у вас есть возможность на проекте, после разработки кидайте ваш код не в файлы локально, а в репо (командное или личное).
Это даст вам несколько преимуществ:
🔹 Вы будите получать опыт разработки и ведения проекта в git по всем канонам. То есть не затрагивая master часть приложения / БД / ETL. Разработка новой фичи / витрины / скрипта будет происходить у вас в новой ветке, а выкат этого в master будет безболезненным с code review.
🔹 Коллеги в любой момент смогут обратиться к вашему коду без вас. Удобно, поскольку совсем недавно я разработал логику для нескольких view, которые отдают данные для BI, и хранил скрипты локально. Конечно, можно посмотреть DDL в БД, но лучше иметь человеческий код под рукой.
🔹 на многих проектах нужен опыт с Git (или аналогами), а тут у вас уже будет набита рука на базовых и необходимых действиях с ним.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1🔥1😁1🤝1
#база_знаний
💻 Оконные функции — звучит страшно, но на деле спасают жизнь.
Друзья, доброго понедельника! Сегодня хочу поделиться, зачем DE знать оконные функции, они же «окошки» или «оконки».
Оконные функции я начал активно изучать только тогда, как увидел их в рабочем коде коллег.
Раньше всегда почему-то откладывал — казалось, что это что-то из высшей математики. Но нет.
👉 На деле — это просто способ посмотреть на соседние строки или преобразовать датафрейм более удобным способом.
Кейс 1: найти последнюю дату по каждому клиенту
Задача: у каждого клиента нужно выбрать только его самый «свежий» договор или заказ.
Обычный
А
Кейс 2: сравнение текущей и предыдущей суммы
Когда нужно вычислить, насколько изменился заказ клиента:
Здесь мы с помощью
Очень часто нужно в продуктовой аналитике или для alert'ов.
Топ-4 самых частых оконных функций:
🔺 ROW_NUMBER() — уникальный номер строки в группе
🔺 RANK() — ранг с пропусками
🔺 DENSE_RANK() — ранг без пропусков
🔺 LAG() / LEAD() — посмотреть назад/вперёд
Оконки — это не только для data analysts.
Data Engineers используют их в витринах, для дедупликации, расчёта активных пользователей, историзации и других задач.
Меньше подзапросов — чище код.
А ты уже используешь оконки?
😎 Да, активно применяю
🤔 Пока только смотрю и не трогаю
Друзья, доброго понедельника! Сегодня хочу поделиться, зачем DE знать оконные функции, они же «окошки» или «оконки».
Оконные функции я начал активно изучать только тогда, как увидел их в рабочем коде коллег.
Раньше всегда почему-то откладывал — казалось, что это что-то из высшей математики. Но нет.
👉 На деле — это просто способ посмотреть на соседние строки или преобразовать датафрейм более удобным способом.
Кейс 1: найти последнюю дату по каждому клиенту
Задача: у каждого клиента нужно выбрать только его самый «свежий» договор или заказ.
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY contract_date DESC) AS rn
FROM contracts
) t
WHERE rn = 1;
Обычный
GROUP BY
тут не поможет — он не подтянет все остальные поля.А
ROW_NUMBER()
с сортировкой — идеально. 👌Кейс 2: сравнение текущей и предыдущей суммы
Когда нужно вычислить, насколько изменился заказ клиента:
SELECT *,
amount - LAG(amount) OVER (PARTITION BY client_id ORDER BY order_date) AS delta
FROM orders;
Здесь мы с помощью
LAG()
смотрим назад и сравниваем текущую сумму с предыдущей.Очень часто нужно в продуктовой аналитике или для alert'ов.
Топ-4 самых частых оконных функций:
Оконки — это не только для data analysts.
Data Engineers используют их в витринах, для дедупликации, расчёта активных пользователей, историзации и других задач.
Меньше подзапросов — чище код.
А ты уже используешь оконки?
😎 Да, активно применяю
🤔 Пока только смотрю и не трогаю
Please open Telegram to view this post
VIEW IN TELEGRAM
😎23👍11🤔6
#мысли
😵 Не понимаю SQL — и что?
Когда я только устраивался в первую команду, за плечами у меня был всего один курс по SQL на Stepik.
Я выучил SELECT, WHERE, GROUP BY, чуть-чуть JOIN — и почувствовал, что этого мало.
Пошёл в документацию PostgreSQL…
И честно? Почти ничего не понял.
Куда смотреть? Какие функции читать? Что вообще важное для работы, а что пока рано?
Я залипал на статьях, не запоминал примеры, перегружался.
И вот что я тогда понял:
▫️ Не надо пытаться выучить всё сразу.
▫️ Не надо читать теорию «про запас».
⬜️ Есть задача → думай, как её решить.
⬜️ Чувствуешь, что не хватает чего-то → гугли, лезь в доку точечно.
⬜️ Применяешь — запоминаешь. Видишь результат — растёшь.
💡 Работа от задачи — самый надёжный способ учиться.
Ты не обязан понимать оконные функции, если ещё не сталкивался с задачей по «поиску последних записей».
Ты не обязан лезть в аналитические витрины, если не знаешь даже, как посчитать суммы по группам.
Начни с малого.
Один день — одна команда.
Одна задача — одно решение.
А ты как учишь SQL?
🔥 От задачи к коду
👍 Сначала читаю теорию
P.S. Подходы применимы везде. Если у вас есть рабочие техники и приемы, поделитесь в комментах 😀
😵 Не понимаю SQL — и что?
Когда я только устраивался в первую команду, за плечами у меня был всего один курс по SQL на Stepik.
Я выучил SELECT, WHERE, GROUP BY, чуть-чуть JOIN — и почувствовал, что этого мало.
Пошёл в документацию PostgreSQL…
И честно? Почти ничего не понял.
Куда смотреть? Какие функции читать? Что вообще важное для работы, а что пока рано?
Я залипал на статьях, не запоминал примеры, перегружался.
И вот что я тогда понял:
Ты не обязан понимать оконные функции, если ещё не сталкивался с задачей по «поиску последних записей».
Ты не обязан лезть в аналитические витрины, если не знаешь даже, как посчитать суммы по группам.
Начни с малого.
Один день — одна команда.
Одна задача — одно решение.
А ты как учишь SQL?
🔥 От задачи к коду
👍 Сначала читаю теорию
P.S. Подходы применимы везде. Если у вас есть рабочие техники и приемы, поделитесь в комментах 😀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍12❤4👌1
#вопрос
❓ JOIN или EXISTS — что выбрать?
У тебя есть две таблицы, и нужно проверить, есть ли для строки в одной таблице соответствие в другой.
Ты что используешь:
На первый взгляд — оба варианта работают. Но есть нюанс.
Несколько советов, если решишь попробовать EXISTS:
🔺 EXISTS не возвращает данные — только говорит: «да, строка есть».
🔺 Работает быстрее, потому что останавливается на первой найденной строке.
🔺 Помогает избежать дублей, которые часто ловишь в JOIN.
👉 Если нужен только факт, что клиент существует — EXISTS часто эффективнее.
А если нужно подтянуть данные — тогда JOIN.
P.S. Я сам долго не пользовался EXISTS, пока не начал ловить дубли в отчётах.
А ты как выбираешь?
🔥EXISTS — если нужна проверка
😎 JOIN — всегда привычнее
Персонажей делал сам, чтобы их образ был максимально подходящим.
У тебя есть две таблицы, и нужно проверить, есть ли для строки в одной таблице соответствие в другой.
Ты что используешь:
-- EXISTS
SELECT *
FROM orders o
WHERE EXISTS (
SELECT 1 FROM clients c WHERE c.client_id = o.client_id
);
-- или JOIN?
SELECT o.*
FROM orders o
JOIN clients c ON c.client_id = o.client_id;
На первый взгляд — оба варианта работают. Но есть нюанс.
Несколько советов, если решишь попробовать EXISTS:
👉 Если нужен только факт, что клиент существует — EXISTS часто эффективнее.
А если нужно подтянуть данные — тогда JOIN.
P.S. Я сам долго не пользовался EXISTS, пока не начал ловить дубли в отчётах.
А ты как выбираешь?
🔥EXISTS — если нужна проверка
😎 JOIN — всегда привычнее
Персонажей делал сам, чтобы их образ был максимально подходящим.
Please open Telegram to view this post
VIEW IN TELEGRAM
😎16👍7🔥6
#путь_de
🤦♂️ Как я однажды заджойнил не туда
Вроде бы простая задача — соединить клиентов с заказами.
Берём client_id, пишем JOIN, получаем отчёт…
А дальше — что-то пошло не так.
В отчёте вдруг стало в 4 раза больше клиентов, чем должно быть.
Такого числа пользователей в системе быть просто не могло.
Начал копать:
🔹 таблица с клиентами оказалась без фильтрации по активным,
🔹 плюс дубли, которые я не удалил,
🔹 плюс забыл, что в таких случаях нужно many-to-one, а не many-to-many.
С тех пор прежде чем джойнить — думаю:
🔺 Какой ключ?
🔺 Это точно one-to-one или one-to-many?
🔺 Нужна ли фильтрация или дедупликация?
И главное — понимать бизнес-смысл таблицы, а не просто “ну тут вроде client_id есть”.
🔸 Итог: таблица похудела, отчёт стал вменяемым, и я запомнил это надолго.
А у тебя бывали такие косяки, когда отчёт “раздувался до луны”? 🤯
Расскажи в комментах 👇
🤦♂️ Как я однажды заджойнил не туда
Вроде бы простая задача — соединить клиентов с заказами.
Берём client_id, пишем JOIN, получаем отчёт…
А дальше — что-то пошло не так.
В отчёте вдруг стало в 4 раза больше клиентов, чем должно быть.
Такого числа пользователей в системе быть просто не могло.
Начал копать:
С тех пор прежде чем джойнить — думаю:
И главное — понимать бизнес-смысл таблицы, а не просто “ну тут вроде client_id есть”.
А у тебя бывали такие косяки, когда отчёт “раздувался до луны”? 🤯
Расскажи в комментах 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11😁2❤1
🤯 Пятничный опрос: что бесит в SQL больше всего?
Anonymous Poll
8%
SELECT * в проде, потому что «так быстрее»
19%
GROUP BY 1,2,3 - и попробуй пойми, что где
8%
LEFT JOIN, который превращается в CROSS JOIN из-за бага
6%
HAVING вместо WHERE (и наоборот)
57%
Вложенный SELECT в FROM, которого еще 2 подзапроса внутри
#база_знаний
ROWS vs RANGE — тонкая грань при работе с датами
Друзья, привет, с новой рабочей неделей ✨
Сегодня поделюсь небольшим на первый взгляд, но существенным нюансом при работе с ранжированием по датам оконками. Несколько раз сам попадал на этом 😅
🔸В чём суть?
ROWS — работает построчно, на уровне физического порядка.
RANGE — работает по значениям в ORDER BY. Особенно опасно с датами и числами с повторами.
А теперь то же с ROWS:
Теперь считаем ровно 7 последних строк — вне зависимости от того, в какой день они были. Это скользящее окно по строкам, не по датам.
🔸Подвохи:
RANGE работает только с одноуровневым ORDER BY.
(нельзя ORDER BY col1, col2 + RANGE в PostgreSQL)
RANGE — может "захватывать" слишком много строк, если в один день много событий.
ROWS — проще, детерминированно, часто предпочтительнее.
🔸Что выбрать?
Если хочешь чёткое "n последних строк" → ROWS
Хочешь "всё, что в пределах X дней/часов" → RANGE INTERVAL ...
Но проверь, как оно работает в твоей СУБД. В PostgreSQL — RANGE INTERVAL появился с версии 14, если не ошибаюсь.
Ты знал об этом различии? Используешь RANGE в проде? (Я не использую 🙂↔️).
👍 - конечно знаю про различие
🔥 - не знал, но теперь все схвачено
ROWS vs RANGE — тонкая грань при работе с датами
Друзья, привет, с новой рабочей неделей ✨
Сегодня поделюсь небольшим на первый взгляд, но существенным нюансом при работе с ранжированием по датам оконками. Несколько раз сам попадал на этом 😅
🔸В чём суть?
ROWS — работает построчно, на уровне физического порядка.
RANGE — работает по значениям в ORDER BY. Особенно опасно с датами и числами с повторами.
SELECT
order_id, order_date,
amount,
SUM(amount) OVER (
ORDER BY order_date
RANGE BETWEEN INTERVAL '7 day' PRECEDING AND CURRENT ROW
) AS week_sum
FROM orders;
Звучит как: "посчитать сумму за последние 7 дней". Но RANGE ищет все строки с order_date в пределах интервала, а не 7 последних строк. Если у тебя несколько заказов в один день, все они попадут.А теперь то же с ROWS:
SUM(amount) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
)
Теперь считаем ровно 7 последних строк — вне зависимости от того, в какой день они были. Это скользящее окно по строкам, не по датам.
🔸Подвохи:
RANGE работает только с одноуровневым ORDER BY.
(нельзя ORDER BY col1, col2 + RANGE в PostgreSQL)
RANGE — может "захватывать" слишком много строк, если в один день много событий.
ROWS — проще, детерминированно, часто предпочтительнее.
🔸Что выбрать?
Если хочешь чёткое "n последних строк" → ROWS
Хочешь "всё, что в пределах X дней/часов" → RANGE INTERVAL ...
Но проверь, как оно работает в твоей СУБД. В PostgreSQL — RANGE INTERVAL появился с версии 14, если не ошибаюсь.
Ты знал об этом различии? Используешь RANGE в проде? (Я не использую 🙂↔️).
👍 - конечно знаю про различие
🔥 - не знал, но теперь все схвачено
🔥15👍7👌1
#мысли
💭 Честность с собой в обучении
Раньше я проходил курсы просто для галочки, чтобы был сертификат. Думал, что он подтверждает наличие у меня знаний.
Сертификат — есть. Глава — закрыта. Всё ✅
🤔 В этом, кстати, есть своя логика. На старте хочется набить портфолио «корочками», чтобы хоть как-то зацепиться.
Попадаешь на проект — и вскоре понимаешь:
никому не интересны твои сертификаты.
Важна только одна вещь — насколько глубоко ты реально в теме.
📚 Сейчас я стараюсь по-другому подходить к обучению:
🔹Когда смотрю видео — я лезу в теорию глубже.
🔹Если читаю про SQL-функции — проверяю, как они работают на моих данных, генерирую тестовые данные.
🔹Если вижу паттерн в чужом коде — пытаюсь воспроизвести и осознать его логику.
Когда ты так нарабатываешь опыт, то начинаешь видеть закономерности, и в этом смысле — обучение становится не задачей в таск трекере, а способом думать. Типовые задачи становятся частью большой системы, элементы которой ты идентифицируешь и уже знаешь, какие подходы применять.
А как у тебя? Учишься «для галочки» или стараешься впитать по-настоящему?
— Поделись, как ты понял, что знания начинают работать.
💭 Честность с собой в обучении
Раньше я проходил курсы просто для галочки, чтобы был сертификат. Думал, что он подтверждает наличие у меня знаний.
Сертификат — есть. Глава — закрыта. Всё ✅
🤔 В этом, кстати, есть своя логика. На старте хочется набить портфолио «корочками», чтобы хоть как-то зацепиться.
Попадаешь на проект — и вскоре понимаешь:
никому не интересны твои сертификаты.
Важна только одна вещь — насколько глубоко ты реально в теме.
📚 Сейчас я стараюсь по-другому подходить к обучению:
🔹Когда смотрю видео — я лезу в теорию глубже.
🔹Если читаю про SQL-функции — проверяю, как они работают на моих данных, генерирую тестовые данные.
🔹Если вижу паттерн в чужом коде — пытаюсь воспроизвести и осознать его логику.
Когда ты так нарабатываешь опыт, то начинаешь видеть закономерности, и в этом смысле — обучение становится не задачей в таск трекере, а способом думать. Типовые задачи становятся частью большой системы, элементы которой ты идентифицируешь и уже знаешь, какие подходы применять.
А как у тебя? Учишься «для галочки» или стараешься впитать по-настоящему?
— Поделись, как ты понял, что знания начинают работать.
🔥7💯5👍3
#вопрос
❓Как найти клиентов с двумя и более заказами в день?
Задача с собеседования, которая звучит просто, но часто ломает логику:
У нас есть таблица orders(client_id, order_date).
Как найти клиентов, которые сделали два и более заказа в один день?
🧩 На первый взгляд — просто:
Но на практике это решение работает только в «стерильной» базе. В боевых проектах — много подводных камней.
⚠️ Нюансы, которые ловят даже опытных
1. order_date — это timestamp, а не date
2. Могут быть дубликаты заказов
3. Могут быть разные временные зоны
4. Не все статусы считаются заказом (если есть доп поле status_id)
⭐️ Доп. вопросы, чтобы проверить глубину знаний:
А как найти клиентов с 2+ заказами подряд в течение суток?
А если нужны не просто 2+, а все даты, где было превышение?
А как посчитать, сколько таких дней было у клиента?
На задачах типа «2+ событий в день» можно отлично прокачать:
- работу с датами и временными зонами,
- агрегации,
- оконные функции,
- производительность группировок на больших объёмах.
👇 А ты разбирал такие задачи?
Стоит потренироваться. А то написал запрос, а потом нашел 100к лишних строк.
Если интересен формат задач с собесов, ставь огонек 🔥
❓Как найти клиентов с двумя и более заказами в день?
Задача с собеседования, которая звучит просто, но часто ломает логику:
У нас есть таблица orders(client_id, order_date).
Как найти клиентов, которые сделали два и более заказа в один день?
🧩 На первый взгляд — просто:
SELECT
client_id,
order_date,
COUNT(*) AS cnt
FROM orders
GROUP BY client_id, order_date
HAVING COUNT(*) > 1;
Но на практике это решение работает только в «стерильной» базе. В боевых проектах — много подводных камней.
⚠️ Нюансы, которые ловят даже опытных
1. order_date — это timestamp, а не date
2. Могут быть дубликаты заказов
3. Могут быть разные временные зоны
4. Не все статусы считаются заказом (если есть доп поле status_id)
⭐️ Доп. вопросы, чтобы проверить глубину знаний:
А как найти клиентов с 2+ заказами подряд в течение суток?
А если нужны не просто 2+, а все даты, где было превышение?
А как посчитать, сколько таких дней было у клиента?
На задачах типа «2+ событий в день» можно отлично прокачать:
- работу с датами и временными зонами,
- агрегации,
- оконные функции,
- производительность группировок на больших объёмах.
👇 А ты разбирал такие задачи?
Стоит потренироваться. А то написал запрос, а потом нашел 100к лишних строк.
Если интересен формат задач с собесов, ставь огонек 🔥
🔥46
#база_знаний
Мои топ-3 SQL-конструкции, без которых я реально не представляю рабочие дни.
Друзья, доброго понедельника. Неделю хочу начать, по традиции, с базы.
Вот простые на первый взгляд штуки, но на них держится очень многое: витрины, отчёты, фичи для моделей и пайплайны.
🔹 CASE WHEN - любимчик
Незаменим, когда нужно сделать pivot — развернуть категории в столбцы.
Например, посчитать агрегаты отдельно по каждому сегменту клиента:
Часто готовлю так фичи для дата-сайентистов или витрины для BI. Очень гибко и удобно.
🔹 COALESCE()
Мой спасатель от NULL'ов. 🙌
Когда соединяешь основную таблицу с внешними справочниками — всегда есть риск наткнуться на пустые значения.
Если не поставить 0, потом все расчёты по скидкам могут поехать.
А так — надёжно и предсказуемо 😄
🔹 SUBSTRING() + DATE_TRUNC()
Когда даты приходят криво или просто в текстовом формате — спасаюсь связкой SUBSTRING и DATE_TRUNC.
Например, для группировки событий по месяцам:
🛠 Это мои рабочие кони каждый день.
А у тебя какие конструкции самые ходовые? (SQL / Spark SQL) — расскажи! 👇
Мои топ-3 SQL-конструкции, без которых я реально не представляю рабочие дни.
Друзья, доброго понедельника. Неделю хочу начать, по традиции, с базы.
Вот простые на первый взгляд штуки, но на них держится очень многое: витрины, отчёты, фичи для моделей и пайплайны.
🔹 CASE WHEN - любимчик
Незаменим, когда нужно сделать pivot — развернуть категории в столбцы.
Например, посчитать агрегаты отдельно по каждому сегменту клиента:
SUM(CASE WHEN segment = 'A' THEN amount ELSE 0 END) AS segment_a_amount
Часто готовлю так фичи для дата-сайентистов или витрины для BI. Очень гибко и удобно.
🔹 COALESCE()
Мой спасатель от NULL'ов. 🙌
Когда соединяешь основную таблицу с внешними справочниками — всегда есть риск наткнуться на пустые значения.
COALESCE(discount_percent, 0) AS applied_discount
Если не поставить 0, потом все расчёты по скидкам могут поехать.
А так — надёжно и предсказуемо 😄
🔹 SUBSTRING() + DATE_TRUNC()
Когда даты приходят криво или просто в текстовом формате — спасаюсь связкой SUBSTRING и DATE_TRUNC.
Например, для группировки событий по месяцам:
SELECT
SUBSTRING(DATE_TRUNC('month', created_at)::text, 1, 7) AS year_month
FROM events;
🛠 Это мои рабочие кони каждый день.
А у тебя какие конструкции самые ходовые? (SQL / Spark SQL) — расскажи! 👇
❤9👍9🔥4
#мотивация
Учеба - это череда маленьких побед. Кажется, что все будет линейно, но большинство знает, что это провалы и восхождения, процесс крайне нестабильный. И когда ты подступаешься к очередной теме в SQL, Spark или любой другой в DE, ты думаешь "А как это понять, как выучить?"
И главная мысль в том, что учёба в области DE нужна постоянно. Это не покорение одной большой горы, а маленькие победы каждый день. Одна задача. Один новый паттерн, одно новое понимание.
Сегодня ты разобрался, что идет первым, WHERE или GROUP BY.
Завтра - написал нормальный JOIN с ROW_NUMBER().
Послезавтра - построил ETL в Spark, от источника до BI.
И всё это складывается (если постоянно практиковать).
Уже через какое-то время тебе говорят, что ты не просто хорошо пишешь код, а неплохо оптимизируешь запросы, иди ка подскажи!
🌱 Не пытайся обогнать всех. Просто расти каждый день по 1%. И так в любой области кстати: профессия, спорт, хобби.
Я сейчас вспоминаю python, решая каждый день по 10 задач. Беда в том, что знания быстро уходят, если их не применять. Поэтому иногда необходимо создавать для себя искусственный полигон.
👇 Расскажи, какую маленькую победу ты помнишь.
Учеба - это череда маленьких побед. Кажется, что все будет линейно, но большинство знает, что это провалы и восхождения, процесс крайне нестабильный. И когда ты подступаешься к очередной теме в SQL, Spark или любой другой в DE, ты думаешь "А как это понять, как выучить?"
И главная мысль в том, что учёба в области DE нужна постоянно. Это не покорение одной большой горы, а маленькие победы каждый день. Одна задача. Один новый паттерн, одно новое понимание.
Сегодня ты разобрался, что идет первым, WHERE или GROUP BY.
Завтра - написал нормальный JOIN с ROW_NUMBER().
Послезавтра - построил ETL в Spark, от источника до BI.
И всё это складывается (если постоянно практиковать).
Уже через какое-то время тебе говорят, что ты не просто хорошо пишешь код, а неплохо оптимизируешь запросы, иди ка подскажи!
🌱 Не пытайся обогнать всех. Просто расти каждый день по 1%. И так в любой области кстати: профессия, спорт, хобби.
Я сейчас вспоминаю python, решая каждый день по 10 задач. Беда в том, что знания быстро уходят, если их не применять. Поэтому иногда необходимо создавать для себя искусственный полигон.
👇 Расскажи, какую маленькую победу ты помнишь.
💯15❤4🔥4👍1
#вопрос
❓Как найти “возвраты” клиента в течение 7 дней?
Вижу, что вам понравился формат задач с собесов, тогда продолжаем.
📆 Представь, что ты смотришь на таблицу заказов и хочешь понять:
а кто из клиентов вернулся за покупкой в течение недели после предыдущего заказа?
Вроде простая, но с подводными камнями.
🙄 Что здесь происходит:
Мы берём текущий заказ и смотрим вперёд (через LEAD) — был ли следующий и когда.
Сравниваем даты: если следующий заказ был в течение 7 дней → это повтор. Фильтрация отсеет всё, кроме недельных интервалов.
❓ Но вот теперь начинаются вопросы, с которыми валили кандидатов:
1. А если у клиента было 3 заказа подряд с интервалом 2 дня — как будет считаться?
2. А если два заказа в один день? LEAD их правильно выстроит?
3. Что делать с отменёнными заказами?
4. Нужно ли нормализовать order_date до DATE(order_date) (а если там timestamp)?
5. Можно ли вместо LEAD() сделать LAG() и считать "возврат" наоборот — от следующей даты назад?
6. А если нужно подсчитать долю клиентов, которые вернулись в течение 7 дней?
📌 Такие задачи хороши тем, что они простые на старте — но требуют понимания оконных функций и аккуратного отношения к данным.
Я так смотрю, что почти все задачи такого формата идут с расчетом на применение оконок.
В копилку задачек для тренировки 💪🏻
А ты бы как решил? А доп вопросы? Традиционно, 🔥 если заходит.
❓Как найти “возвраты” клиента в течение 7 дней?
Вижу, что вам понравился формат задач с собесов, тогда продолжаем.
📆 Представь, что ты смотришь на таблицу заказов и хочешь понять:
а кто из клиентов вернулся за покупкой в течение недели после предыдущего заказа?
Вроде простая, но с подводными камнями.
WITH client_orders AS (
SELECT
client_id,
order_date,
LEAD(order_date) OVER (
PARTITION BY client_id ORDER BY order_date
) AS next_order
FROM orders
)
SELECT
client_id,
order_date,
next_order
FROM client_orders
WHERE next_order IS NOT NULL
AND next_order <= order_date + INTERVAL '7 days';
🙄 Что здесь происходит:
Мы берём текущий заказ и смотрим вперёд (через LEAD) — был ли следующий и когда.
Сравниваем даты: если следующий заказ был в течение 7 дней → это повтор. Фильтрация отсеет всё, кроме недельных интервалов.
❓ Но вот теперь начинаются вопросы, с которыми валили кандидатов:
1. А если у клиента было 3 заказа подряд с интервалом 2 дня — как будет считаться?
2. А если два заказа в один день? LEAD их правильно выстроит?
3. Что делать с отменёнными заказами?
4. Нужно ли нормализовать order_date до DATE(order_date) (а если там timestamp)?
5. Можно ли вместо LEAD() сделать LAG() и считать "возврат" наоборот — от следующей даты назад?
6. А если нужно подсчитать долю клиентов, которые вернулись в течение 7 дней?
📌 Такие задачи хороши тем, что они простые на старте — но требуют понимания оконных функций и аккуратного отношения к данным.
Я так смотрю, что почти все задачи такого формата идут с расчетом на применение оконок.
В копилку задачек для тренировки 💪🏻
А ты бы как решил? А доп вопросы? Традиционно, 🔥 если заходит.
🔥25💯2❤1
#база_знаний
🔥 Боль UNPIVOT в Greenplum
Всем привет после майских — пора включаться в рабочие процессы, как бы тяжело это ни было 😅
Вспомнил один рабочий кейс с проекта, который в своё время стал для меня настоящим инсайтом. Я готовил данные для BI дашбордов и отдал таблицу, которая сломала все графики. Все полетело к черту, а я гадал "а как же сделать правильно и не руками?".
Тогда впервые понял, как простой CASE + VALUES может заменить весь UNION ALL и спасти от 50 строк повторяющегося кода.
Пример условный, чтобы понять механику.
Визуально выглядит хорошо, но для построения отчетов - плохо. Гибкости ноль. Нужно, чтобы в BI автоматически с применением нужного фильтра отчет сам перестраивался. А для этого нужно сделать поле subcategory:
То есть свернуть все поля (сделать обратный pivot) до одного поля, а дополнительно создать поле value.
🛠 В Greenplum UNPIVOT напрямую не поддерживается, но решение есть — и оно оказалось очень элегантным:
С тех пор — я фанат CASE.
(Кстати, о CASE я писал отдельно 👉 тут)
💡 Мораль:
PIVOT удобно для человека.
UNPIVOT удобно для системы.
🔽 А ты сталкивался с таким?
👍 — Знал об этом трюке
🔥 — Не знал, и это было полезно
Если работаешь с BI — сохрани этот паттерн.
Однажды он тебе точно пригодится.
🔥 Боль UNPIVOT в Greenplum
Всем привет после майских — пора включаться в рабочие процессы, как бы тяжело это ни было 😅
Вспомнил один рабочий кейс с проекта, который в своё время стал для меня настоящим инсайтом. Я готовил данные для BI дашбордов и отдал таблицу, которая сломала все графики. Все полетело к черту, а я гадал "а как же сделать правильно и не руками?".
Тогда впервые понял, как простой CASE + VALUES может заменить весь UNION ALL и спасти от 50 строк повторяющегося кода.
Пример условный, чтобы понять механику.
report_date category clicks views purchases
2024-05-01 sport 120 350 5
2024-05-01 tech 200 500 12
Визуально выглядит хорошо, но для построения отчетов - плохо. Гибкости ноль. Нужно, чтобы в BI автоматически с применением нужного фильтра отчет сам перестраивался. А для этого нужно сделать поле subcategory:
report_date category subcategory value
2024-05-01 sport clicks 120
2024-05-01 sport views 350
2024-05-01 sport purchases 5
То есть свернуть все поля (сделать обратный pivot) до одного поля, а дополнительно создать поле value.
🛠 В Greenplum UNPIVOT напрямую не поддерживается, но решение есть — и оно оказалось очень элегантным:
SELECT
report_date,
category,
subcategory,
CASE subcategory
WHEN 'clicks' THEN clicks
WHEN 'views' THEN views
WHEN 'purchases' THEN purchases
END::numeric AS value
FROM metrics,
(VALUES ('clicks'), ('views'), ('purchases')) AS sub(subcategory);
С тех пор — я фанат CASE.
(Кстати, о CASE я писал отдельно 👉 тут)
💡 Мораль:
PIVOT удобно для человека.
UNPIVOT удобно для системы.
🔽 А ты сталкивался с таким?
👍 — Знал об этом трюке
🔥 — Не знал, и это было полезно
Если работаешь с BI — сохрани этот паттерн.
Однажды он тебе точно пригодится.
🔥18👍3
#база_знаний
📆 Пропущенные даты в активности (поиск дыр)
Когда вы анализируете поведение пользователей, часто смотрите на дни активности — когда был заказ, вход в приложение или другое событие.
Но бывает важно сделать наоборот: а в какие дни активности не было?
Например, из всего календарного месяца нужно найти даты, когда клиент ничего не делал. Это помогает выявить падение интереса, возможный churn или просто дыры в трекинге.
⏳ Временные ряды — как дополнение к практике
Я сам начал работать с временными рядами только в Spark.
Но это прям классный приём, Джуны, берите на вооружение:
создаёте “идеальный” календарь — и сравниваете его с реальными действиями пользователя.
Кейс в Greenplum / Postgres
А если в Spark?
В Spark нет generate_series, но sequence + explode отлично решает задачу.
🤔 Зачем это использовать?
• Находить дни без активности.
• Проверять трекинг событий (вдруг что-то не пишется?).
• Построить нормальные графики в BI — без пропусков по датам.
• Делать анализ удержания и активных дней.
Если хочешь потренироваться, попробуй адаптировать запрос под клиента — чтобы находить “пустые” дни для каждого client_id.
Это уже уровень middle, но отличная тренировка мышления “как аналитик”.
Если интересно — напишу разбор с решением! Но с вас реакции! Сохраняйте материал.
📆 Пропущенные даты в активности (поиск дыр)
Когда вы анализируете поведение пользователей, часто смотрите на дни активности — когда был заказ, вход в приложение или другое событие.
Но бывает важно сделать наоборот: а в какие дни активности не было?
Например, из всего календарного месяца нужно найти даты, когда клиент ничего не делал. Это помогает выявить падение интереса, возможный churn или просто дыры в трекинге.
⏳ Временные ряды — как дополнение к практике
Я сам начал работать с временными рядами только в Spark.
Но это прям классный приём, Джуны, берите на вооружение:
создаёте “идеальный” календарь — и сравниваете его с реальными действиями пользователя.
Кейс в Greenplum / Postgres
WITH calendar AS (
SELECT generate_series('2024-01-01', '2024-01-31', INTERVAL '1 day') AS day
),
activity AS (
SELECT DISTINCT DATE(order_date) AS active_day
FROM orders
)
SELECT day
FROM calendar
LEFT JOIN activity ON day = active_day
WHERE active_day IS NULL;
А если в Spark?
WITH calendar AS (
SELECT explode(sequence(to_date('2024-01-01'), to_date('2024-01-31'), interval 1 day)) AS day
),
activity AS (
SELECT DISTINCT to_date(order_date) AS active_day
FROM orders
)
SELECT day
FROM calendar
LEFT JOIN activity ON day = active_day
WHERE active_day IS NULL;
В Spark нет generate_series, но sequence + explode отлично решает задачу.
🤔 Зачем это использовать?
• Находить дни без активности.
• Проверять трекинг событий (вдруг что-то не пишется?).
• Построить нормальные графики в BI — без пропусков по датам.
• Делать анализ удержания и активных дней.
Если хочешь потренироваться, попробуй адаптировать запрос под клиента — чтобы находить “пустые” дни для каждого client_id.
Это уже уровень middle, но отличная тренировка мышления “как аналитик”.
Если интересно — напишу разбор с решением! Но с вас реакции! Сохраняйте материал.
👍19❤2👌1
☝🏻Полезный SQL-приём: NULLIF
Совсем недавно узнал такой неочевидный прием, что когда нужно посчитать что-то вроде:
... бывает, что clicks = 0, и тогда произойдёт ошибка деления на ноль.
Стандартный способ — использовать CASE:
Это правильно, но громоздко.
Есть короткий способ — функция NULLIF:
Как работает:
🔸 NULLIF(clicks, 0) вернёт NULL, если clicks = 0
🔸 Если clicks ≠ 0, то вернёт само значение clicks
А в SQL, как известно:
То есть:
🔸 если clicks = 5, то amount / 5
🔸 если clicks = 0, то amount / NULL → результат будет NULL, без ошибки
Это удобно, если тебе важна устойчивость запроса:
🔸 ты избегаешь падения из-за деления на ноль
🔸 а при этом не теряешь логику: нулевые значения просто будут как NULL
Когда использовать:
🔸 при расчётах CTR, CPC и других метрик с делением
🔸 в агрегатах: AVG(amount / NULLIF(clicks, 0))
🔸 в отчётах, где важна стабильность
Кажется, что функция довольно полезна, но ее потенциал для себя мне предстоит раскрыть!
❓Ты используешь NULLIF в своих запросах?
Может, есть другие короткие трюки, которые часто выручают?
Совсем недавно узнал такой неочевидный прием, что когда нужно посчитать что-то вроде:
amount / clicks
... бывает, что clicks = 0, и тогда произойдёт ошибка деления на ноль.
Стандартный способ — использовать CASE:
CASE
WHEN clicks = 0 THEN NULL
ELSE amount / clicks
END
Это правильно, но громоздко.
Есть короткий способ — функция NULLIF:
amount / NULLIF(clicks, 0)
Как работает:
🔸 NULLIF(clicks, 0) вернёт NULL, если clicks = 0
🔸 Если clicks ≠ 0, то вернёт само значение clicks
А в SQL, как известно:
Любая операция с NULL даёт NULL, но не вызывает ошибку.
То есть:
🔸 если clicks = 5, то amount / 5
🔸 если clicks = 0, то amount / NULL → результат будет NULL, без ошибки
Это удобно, если тебе важна устойчивость запроса:
🔸 ты избегаешь падения из-за деления на ноль
🔸 а при этом не теряешь логику: нулевые значения просто будут как NULL
Когда использовать:
🔸 при расчётах CTR, CPC и других метрик с делением
🔸 в агрегатах: AVG(amount / NULLIF(clicks, 0))
🔸 в отчётах, где важна стабильность
Кажется, что функция довольно полезна, но ее потенциал для себя мне предстоит раскрыть!
❓Ты используешь NULLIF в своих запросах?
Может, есть другие короткие трюки, которые часто выручают?
🔥19👍2👌1