给定一个包含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
作为结果。我不需要用户细分的结果。
答案 0 :(得分:2)
查询将条纹计数保留在变量中,一旦出现间隙,它就会将计数重置为大的负数。然后它返回最大的条纹。
根据用户可以拥有多少票数,您可能需要将-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
注意,如果在本帖发布之日运行,小提琴只会返回正确的条纹:)
更新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
,具体取决于您是否要在连胜中加入第一个投票。
答案 1 :(得分:0)
以下是它的基本要点:
使用您开始使用的查询按日期创建有序集,然后使用运行总计将其换行以获取计数,但将结果限制为今天。我从内部查询中删除了用户名,以便在需要时将其应用于外部,或者返回当前匹配的每个人的整个集合。请注意,除非调整样本数据,否则此小提琴仅返回2014年8月12日的结果。
http://sqlfiddle.com/#!2/a8554/21/0
使用:
Create table votes (
id int,
date_created date,
username varchar(10));
insert into votes (id, username,date_created) VALUES
(1, 'bob', '2014-08-10 00:35:22'),
(2, 'sue', '2014-08-10 00:35:22'),
(3, 'bob', '2014-08-11 00:35:22'),
(4, 'mike', '2014-08-11 00:35:22'),
(5, 'bob', '2014-08-12 00:35:22'),
(6, 'mike', '2014-08-12 00:35:22');
然后
SET @runtot:=0;
select SOVUN, SOVDC,
case when SOVUN = PDUN
then @runtot:=@runtot+1
else @runtot:=0 end as RunningTotal
FROM (
SELECT
start_of_Votes.username SOVUN,
Start_of_Votes.Date_Created SOVDC,
previous_day.username PDUN,
Previous_day.date_created PDDC
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)
order by SOVUN, SOVDC) B
返回:
SOVUN SOVDC RUNNINGTOTAL
bob August, 10 2014 00:00:00+0000 0
bob August, 11 2014 00:00:00+0000 1
bob August, 12 2014 00:00:00+0000 2
mike August, 11 2014 00:00:00+0000 0
mike August, 12 2014 00:00:00+0000 1
sue August, 10 2014 00:00:00+0000 0
请注意,您可以在白天进行限制而不将其包装在子查询中,否则运行总计数将无效。您不能提前应用运行总计数,因为必须先订购该集。因此需要两个嵌套的子查询。