我昨天问了这个问题,但我没有把它说得很清楚,所以我要添加一些信息来把一切都说清楚。
考虑以下两个表:
0_12_table
ID userID text timestamp
1 1 bla 2020-08-07 10:30:00
2 1 blub 2020-08-06 11:30:00
3 1 abc 2020-08-05 09:20:00
4 1 def 2020-08-04 06:13:00
5 2 ghi 2020-08-02 08:05:00
6 2 abc 2020-08-05 10:20:00
7 3 def 2020-08-04 07:13:00
8 4 ghi 2020-08-02 09:05:00
9 5 jkl 2020-08-07 06:30:00
10 5 mno 2020-08-08 08:32:00
12_24_table:
ID userID text timestamp
1 1 bla 2020-08-07 19:30:00
2 1 blub 2020-08-06 21:30:00
3 1 abc 2020-08-05 19:20:00
4 2 def 2020-08-04 16:13:00
5 2 ghi 2020-08-02 18:05:00
6 2 abc 2020-08-05 20:20:00
7 3 def 2020-08-04 17:13:00
8 4 ghi 2020-08-02 19:05:00
9 5 jkl 2020-08-07 20:13:00
基本上,用户可以在00:00到12:00之间在数据库中添加一个条目,并在12:01到23:59之间添加一个。
现在,我想奖励他们连续添加条目。每当他们错过了时间表;计数器";不过已重置为0。。。
在上面给出的数据中,userID为1的用户现在将连续3天(在我的时代,现在是上午9点(,但无论何时是在上午12点之后,如果他没有再输入,计数器将设置为0,并且连续结束,因为他错过了为上午添加一个条目。
userID为2、3和4的用户将完全没有连胜记录。如果缺少一个上午或晚上的参赛项目,则连胜总是被取消。
用户ID为5的用户在12:01到23:59的时间段内输入时,将连续出现1,这将增加到2。
我希望你能理解其中的逻辑。重要的是,这并不重要,如果他有10连胜2天前。每当有一个条目丢失时,该条纹都会重置为0。因此,当一天上午12点之前没有进入早盘,或者晚上23点59分之前没有进入时,那么连胜就消失了。它总是用今天作为参考,所以它真的是"直到今天的连续条目";。
到目前为止,我得到的答案似乎很接近:
select min(dte), max(dte), count(*)
from (select dte, (@rn := @rn + 1) as seqnum
from (select dte
from ((select date(timestamp) as dte, 1 as morning, 0 as evening
from morning
) union all
(select date(timestamp) as dte, 0 as morning, 1 as evening
from evening
)
) me
group by dte
having sum(morning) > 0 and sum(evening) > 0
order by dte
) d cross join
(select @rn := 0) params
) me
group by dte - interval seqnum day
order by count(*) desc
limit 1;
然而,到目前为止,我还没有介绍userID,最大的问题是:它只需要最后一次连胜,无论直到今天是否有差距。。但是,如前所述,它总是以今天为参考。
我希望有人能在这里帮助我。
最后一个重要信息:我正在使用MariaDB 10.1.45,所以"WITH";或";ROWNUM(("不可用,目前无法更新。
提前感谢!
在使用窗口函数的最新版本中,这会更简单。但您可以调整变量,为用户获得所有条纹:
select userid, count(*) as length
from (select dte, (@rn := @rn + 1) as seqnum
from (select dte
from ((select userid, date(timestamp) as dte, 1 as morning, 0 as evening
from morning
) union all
(select userid, date(timestamp) as dte, 0 as morning, 1 as evening
from evening
)
) me
group by userid, dte
having sum(morning) > 0 and sum(evening) > 0
order by userid, dte
) d cross join
(select @rn := 0) params
) me
group by userid, dte - interval seqnum day
order by count(*) desc;
事实证明;全局";对于这个问题,序列和局部序列一样有效,所以变量的使用仍然很简单。这些更改针对group by
和order by
子句。
然后,您可以将其用作子查询以获得最大值:
select userid, max(seq)
from (select userid, count(*) as seq
from (select dte, (@rn := @rn + 1) as seqnum
from (select dte
from ((select userid, date(timestamp) as dte, 1 as morning, 0 as evening
from morning
) union all
(select userid, date(timestamp) as dte, 0 as morning, 1 as evening
from evening
)
) me
group by userid, dte
having sum(morning) > 0 and sum(evening) > 0
order by userid, dte
) d cross join
(select @rn := 0) params
) me
group by userid, dte - interval seqnum day
) u
group by userid;
注意:没有条纹的用户将被过滤掉。您可以在外部查询中使用left join
将它们放回。然而,你真的想要一个所有用户的表,而不是你的两个单独的表,所以我不介意。