Проверка соответствия требованиям для получения значка

Мы часто получаем вопросы о значке Aficionado (100 последовательных дней). Обычно проблема заключается в том, что пользователь пропустил один или несколько дней из-за различий в часовых поясах между его регионом и временем на сервере.

Я всегда немного путался в запросе, который используется для выдачи значка. Думаю, теперь я понимаю его. Вот запрос для Data Explorer, использующий аналогичную логику. Он возвращает периоды последовательных посещений пользователя. Для каждого периода последовательных посещений он возвращает дату начала, количество последовательных дней и дату окончания. По умолчанию возвращаются все периоды с 10 или более посещениями. Чтобы узнать, какие дни пропустил пользователь, установите параметр min_days в значение 1.

Если значение period_end, возвращаемое в первой строке результатов, совпадает с текущей датой, когда вы выполняете запрос, пользователь всё ещё претендует на значок.

--[params]
-- string :username
-- int :min_days = 10

WITH consecutive_visits AS (
  SELECT user_id,
       visited_at,
       -- Значение s будет одинаковым для каждой группы последовательных дней
       visited_at - (DENSE_RANK() OVER (PARTITION BY user_id ORDER BY visited_at))::int s
    FROM user_visits
    WHERE user_id = (SELECT id FROM users WHERE username = :username)
)

SELECT
MIN(visited_at) period_start,
COUNT(*) AS consecutive_days,
MAX(visited_at) period_end
FROM consecutive_visits
GROUP BY user_id, s
HAVING COUNT(*) >= :min_days
ORDER BY period_start DESC