-- Задание 1 SELECT name, created_at::date, current_date - created_at::date AS days_since_registration FROM mnoskov.users WHERE is_active = TRUE AND current_date - created_at::date > 180 ORDER BY days_since_registration desc; -- Очень старым пользователям можно кинуть рассылку на почту на подобии 'Представляете, мы вместе уже 777 дней, вот вам купон на скидку' -- Удобнее вычитать ::date, чтобы days_since_registration красиво выглядел в таблице -- Задание 2 SELECT name, lower(email) AS email_clean, substring(email FROM POSITION('@' IN email) + 1) AS domain FROM mnoskov.users WHERE email IS NOT NULL ORDER BY domain, name; -- email приводят к нижнему регистру для нормализации записи, а зачем выделяют домен не понимаю, может быть для аналитики по типу кто какой почтой пользуется -- Получу NULL в domain -- Задание 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 mnoskov.users ORDER BY age; -- Почему удобнее держать логику сегментации в SQL (CASE), а не только в коде приложения? Я не понял этот вопрос. -- Если забыть в ветку ELSE, то будет NULL у тех кто никуда не попал -- Задание 4 SELECT name, created_at::date, current_date - created_at::date AS days_since_registration, CASE WHEN created_at >= current_date - INTERVAL '30 days' THEN 'hot' ELSE 'regular' END AS hot_flag FROM mnoskov.users WHERE created_at >= current_date - INTERVAL '30 days'; -- Фильтрация по дате в WHERE исключает неподходящие варианты, а простой CASE в нашем случае возвращает результат в виде двух вариантов - подошло/не подошло и эти оба варианта остаются в таблице -- Стоит запускать какие нибудь привлекательные варианты со скидкам и акциями, чтобы удержать пользователся -- Задание 5 SELECT count(*) AS total_users, count(email) AS with_email, count(*) - count(email) AS without_email, ((count(*) - count(email))::float / count(*)) * 100.0 AS percent_without_email FROM mnoskov.users; -- Агрегаты дают более точную информацию чем просто на глаз -- Я бы предолжил запустить активно вылезающие блоки с предложением зарегестрироваться, или же запретить пользоваение продуктом без регистрации -- Задание 6 SELECT name, current_date - created_at::date AS days_since_registraion, CASE WHEN current_date - created_at::date <= 30 THEN 'new' WHEN current_date - created_at::date BETWEEN 31 AND 180 THEN 'middle' WHEN current_date - created_at::date > 180 THEN 'old' END AS tenure_group, is_active FROM mnoskov.users ORDER BY tenure_group, days_since_registraion; -- Сегментация по стажу говорит о опыте человека, а по возрасту только о возрасте -- Пересчитывать каждый день - плюсы: не занимает места на диске, минусы: тратит больше вычислительных ресурсов, а если хранить статическое поле, то все наоборот