Представим таблицу
logins:user_id INT,
login_date DATEНужно определить: для каждого пользователя — самую длинную непрерывную последовательность дней, когда он заходил на сайт (без пропущенных дат).
💡 Хитрый приём: если пронумеровать входы с
ROW_NUMBER(), то разность login_date - row_number будет постоянной в рамках серии подряд идущих дней. Это позволяет сгруппировать такие серии и посчитать их длину.Вот решение:
WITH login_ranked AS (
SELECT
user_id,
login_date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) AS rn
FROM logins
),
grouped AS (
SELECT
user_id,
login_date,
DATE_SUB(login_date, INTERVAL rn DAY) AS grp
FROM login_ranked
),
group_lengths AS (
SELECT
user_id,
grp,
COUNT(*) AS streak_length
FROM grouped
GROUP BY user_id, grp
)
SELECT
user_id,
MAX(streak_length) AS max_consecutive_days
FROM group_lengths
GROUP BY user_id
ORDER BY max_consecutive_days DESC;
📌 Подходит для задач с непрерывной активностью, логами, аналитикой по клиентам и временным последовательностям.