From d5155bed65efd7fc52d7318eba4f76c0b9f83c3d Mon Sep 17 00:00:00 2001 From: Dmitry Medvedev Date: Sun, 31 May 2026 23:21:45 +0500 Subject: [PATCH] add tasks with function, string, logic --- dmedvedev/function: date.sql | 109 +++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 dmedvedev/function: date.sql diff --git a/dmedvedev/function: date.sql b/dmedvedev/function: date.sql new file mode 100644 index 0000000..e4a603c --- /dev/null +++ b/dmedvedev/function: date.sql @@ -0,0 +1,109 @@ +--task 1 +--Задача 1. Давность регистрации пользователей +SELECT name, created_at::date AS created_date, CURRENT_DATE - created_at::date AS date_since_registration +FROM users u +WHERE CURRENT_DATE - created_at::date > 180 +ORDER BY date_since_registration DESC + +/*Как бы ты использовал такое поле в реальном продукте (что можно делать с очень «старыми» пользователями)? +В зависимости от их активности можно предложить те или иные плюшки. + +Почему удобнее сразу вычитать created_at::date, а не created_at как timestamp? +Потому что CURRENT_DATE - это просто текущая дата без учета времени +*/ + +--task 2 +--Задача 2. Нормализация email и доменов +SELECT + name, + LOWER(email) AS email_clean, + substring(LOWER(email) FROM POSITION('@' IN email) +1) AS domain +FROM users +WHERE email IS NOT NULL +ORDER BY domain, name +/* +Зачем в реальных системах приводят email к нижнему регистру и выделяют домен отдельно? +Возможно потому что люди могут писать с разным регистром, и если бы это учитывалось, то одинаковые почтовые ящики с разными регистрами были бы совершенно разными. +А системе не нужны дубликаты с разными регистрами. + +Что будет, если по ошибке не отфильтровать email IS NOT NULL (что получишь в domain)? +Получу NULL,человек не заполнил ячейку имэйла при регистрации. +*/ + +--task 3 +--Задача 3. Сегменты по возрасту +SELECT + name, + age, + CASE + WHEN age < 25 THEN 'young' + WHEN age BETWEEN 25 and 35 THEN 'adult' + WHEN age > 35 THEN 'senior' + END AS age_group +FROM users +ORDER BY age + +/* +Почему удобнее держать логику сегментации в SQL (CASE), а не только в коде приложения? +Возможно, Так проще работать с данными + +Что произойдёт, если в CASE забыть ветку ELSE (что получат пользователи, не попавшие ни в одно условие)? +У них появятся значения NULL +*/ + +--task 4 +--Задача 4. «Горячие» пользователи по дате и активности +SELECT + name, + created_at::date AS created_date, + CURRENT_DATE - created_at::date AS days_since_registration, + CASE + WHEN (is_active IS TRUE OR CURRENT_DATE - created_at::date <= 30) THEN 'hot' + ELSE 'regular' + END AS hot_flag + +FROM users +WHERE (is_active IS TRUE OR CURRENT_DATE - created_at::date <= 30) +/*Чем отличается фильтрация по дате в WHERE от простого CASE с меткой 'hot', но без фильтрации? +Последовательностью выполнения, различными функциями (в одном фильтрация идет, в другом просто присваивание определенному условию наименования в дополнительном столбце) + +Какие типы рассылок/кампаний логично запускать только на «горячих»? + +*/ + +--task 5 +--Задача 5. Качество данных по email +SELECT + COUNT(*) AS total_users, + COUNT(email) AS with_email, + COUNT(*) - COUNT(email) AS without_email, + (COUNT(*) - COUNT(email)) * 100.0 / COUNT(*) AS dolya +FROM users + +/*Почему для проверки «долей» и «заполненности» полей лучше использовать агрегаты в SQL, а не просто «на глаз» смотреть на таблицу? +То ли я туп, то ли вопрос с подковыркой для меня. Если значений может быть миллион, то как еще это делать, если не через агрегаты? + +Какие действия по данным ты бы предложил продукту, если доля пользователей без email слишком большая? +Как минимум при регистрации сделать поле "имэйл" обязательным для заполнения. +*/ + +--task 6 +--Задача 6. «Стаж» пользователя и его группа +SELECT + name, + CURRENT_DATE - created_at::date AS says_since_registration, + CASE + WHEN CURRENT_DATE - created_at::date <= 30 THEN 'new' + WHEN CURRENT_DATE - created_at::date > 180 THEN 'old' + ELSE 'middle' + END AS tenure_group, + is_active +FROM users +ORDER BY tenure_group, says_since_registration + +/* +Чем сегментация по «стажу» отличается по смыслу от сегментации по возрасту? + +Если пересчитывать tenure_group прямо в SQL каждый день, какие плюсы и минусы по сравнению с хранением статического поля segment? +Можно будет понимать в динамике сколько старичков и сколько молодых, можно будет видеть приросты пользователей за каждый день. +*/