Given a bunch of records (which represent checkins in my app) with a timestamp field, what would be a good way to determine the current streak of consecutive checkins?
In other words, with the checkins sorted by checkin time descending, how many records are there until a user missed a day?
Currently I'm using this technique:
SELECT distinct(uca.created_at::date) as created_at
FROM user_challenge_activities as uca INNER JOIN user_challenges as uc
ON user_challenge_id = uc.ID WHERE uc.user_id = #{user.id}
order by (uca.created_at::date) DESC;
...where I cast the checkin timestamps to a date (to end up with e.g. 2012-03-20), then in code, go through the records and increment a counter until the date between the record and the next record is greater than 1 day.
However, this approach seems clumsy to me, and it seems like the sort of thing that Postgres would excel at.
So is there in fact a better way to accomplish this?
with t as (
SELECT distinct(uca.created_at::date) as created_at
FROM user_challenge_activities as uca
INNER JOIN user_challenges as uc ON user_challenge_id = uc.ID
WHERE uc.user_id = #{user.id}
)
select count(*)
from t
where t.create_at > (
select d.d
from generate_series('2010-01-01'::date, CURRENT_DATE, '1 day') d(d)
left outer join t on t.created_at = d.d::date
where t.created_at is null
order by d.d desc
limit 1
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With