Как найти пользователей с визитами между первой датой визита и первой датой плюс 10 дней?
Что проверяют
Умеете ли вы считать дату относительно каждого пользователя, а не относительно одной константы. По сути это задача на удержание: кто вернулся в первые 10 дней после первого визита. Следом спрашивают, как посчитать долю таких пользователей и что делать с границами интервала.
Как отвечать
Сначала уточните условия: считается ли сам первый визит (если да, в выборку попадут все), входит ли десятый день, какой тип у колонки, date или timestamp. Решение в два шага: найти первую дату для каждого пользователя и отфильтровать визиты относительно неё. В PostgreSQL:
WITH v AS (
SELECT user_id,
visit_date::date AS d,
MIN(visit_date::date) OVER (PARTITION BY user_id) AS first_d
FROM visits
)
SELECT DISTINCT user_id
FROM v
WHERE d > first_d
AND d <= first_d + 10;- оконная функция:
MIN() OVER (PARTITION BY user_id)добавляет первую дату к каждой строке без схлопывания, таблица читается один раз; - альтернатива: CTE с
GROUP BY user_idиMIN(visit_date), затемJOINобратно кvisits. Результат тот же; DISTINCT: у пользователя может быть несколько визитов в окне, а нужен список людей;- арифметика дат: в PostgreSQL
date + 10даёт дату, в MySQL то же делаетDATE_ADD(first_d, INTERVAL 10 DAY), в ClickHouseaddDays(first_d, 10).
Долю вернувшихся получите, разделив COUNT(DISTINCT user_id) по этому условию на общее число пользователей.
Где спотыкаются
Подставляют одну фиксированную дату вроде '2023-01-01' для всех. Получается выборка визитов за конкретные дни, а не окно от первого визита каждого пользователя.
Смешивают типы: если visit_date это timestamp, а первая дата приведена к date, условие visit_date BETWEEN first_d AND first_d + 10 отрежет все визиты десятого дня после полуночи.
Пишут WHERE visit_date = MIN(visit_date). Агрегат в WHERE недопустим, для этого и нужен CTE или оконная функция.