практика Функции
This commit is contained in:
@@ -0,0 +1,90 @@
|
|||||||
|
-- Задание 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;
|
||||||
|
-- Сегментация по стажу говорит о опыте человека, а по возрасту только о возрасте
|
||||||
|
-- Пересчитывать каждый день - плюсы: не занимает места на диске, минусы: тратит больше вычислительных ресурсов, а если хранить статическое поле, то все наоборот
|
||||||
Reference in New Issue
Block a user