给定一个包含 timestamp
和 user
列的 MySQL 表,我希望能够计算一个记录存在的连续天数(必须以今天结束)给定的用户。
stackoverflow/google 上的所有示例都涉及查找以前的连续记录,或计算总记录数,但我需要了解他们的当前记录;
我可以使用它来查找前一天有记录的所有日期:
select date(start_of_votes.date_created)
from votes start_of_votes
left join votes previous_day
on start_of_votes.username = previous_day.username
and date(start_of_votes.date_created) - interval 1 day = date(previous_day.date_created)
where previous_day.id is not null
and start_of_votes.username = "bob"
group by date(start_of_votes.date_created) desc
但我只需要计算包含今天记录的范围。
根据请求,一些示例数据:
bob 2014-08-10 00:35:22
sue 2014-08-10 00:35:22
bob 2014-08-11 00:35:22
mike 2014-08-11 00:35:22
bob 2014-08-12 00:35:22
mike 2014-08-12 00:35:22
今天是 2014 年 8 月 12 日:
bob
连续 3 天
sue
目前没有连胜纪录
mike
连续 2 天
此数据是针对每个用户的,因此我将对 bob
运行查询并获得 3
作为结果。我不需要按用户分割的结果。
最佳答案
查询将连续计数保存在一个变量中,一旦出现间隔,它就会将计数重置为一个大的负值。然后返回最大的连胜。
根据用户可以获得多少票,您可能需要将 -99999
更改为更大的(负)值。
select if(max(maxcount) < 0, 0, max(maxcount)) streak
from (
select
if(datediff(@prevDate, datecreated) = 1, @count := @count + 1, @count := -99999) maxcount,
@prevDate := datecreated
from votes v cross join
(select @prevDate := date(curdate() + INTERVAL 1 day), @count := 0) t1
where username = 'bob'
and datecreated <= curdate()
order by datecreated desc
) t1;
http://sqlfiddle.com/#!2/37129/6
更新
另一种变化
select * from (
select datecreated,
@streak := @streak+1 streak,
datediff(curdate(),datecreated) diff
from votes
cross join (select @streak := -1) t1
where username = 'bob'
and datecreated <= curdate()
order by datecreated desc
) t1 where streak = diff
order by streak desc limit 1
http://sqlfiddle.com/#!2/c6dd5b/20
请注意,如果在本文发布之日运行,fiddle 只会返回正确的条纹 :)
更新 2
下面的查询适用于允许同一用户每天多次投票的表,方法是从删除了重复日期的派生表中进行选择。
select * from (
select date_created,
@streak := @streak+1 streak,
datediff(curdate(),date_created) diff
from (
select distinct date(date_created) date_created
from votes where username = 'pinkpopcold'
) t1
cross join (select @streak := -1) t2
order by date_created desc
)
t1 where streak = diff
order by streak desc limit 1
http://sqlfiddle.com/#!2/5fc6d/7
您可能需要将 select *
替换为 select streak + 1
,具体取决于您是否希望在连胜中包含第一票。
关于MySQL 计算当前连胜的连续日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25272098/