用 MySQL 计算连续的天数
Compute consecutive day streaks with MySQL
我有以下 table :
Date | isDone
--------------------
2018-10-01 | 1
2018-10-02 | 1
2018-10-03 | 1
2018-10-04 | 1
2018-10-10 | 0
2018-10-15 | 1
2018-10-16 | 0
2018-10-18 | 1
2018-10-19 | 1
2018-10-20 | 1
每天只能有一行,有 2 个可能的值 0 或 1。一天不一定必须有一行。如果一天没有一行,则该值被视为 0。
我想计算 "current streak" 从当前日期开始完成的任务(isDone 列)。假设我们是 2018-10-20,结果将是 3。现在,我不想计算本月的最大连胜纪录,在本例中为 4(从 2018-10-01 到 2018-10-04)。我想知道计算这个的最佳选择是什么,直接使用 SQL (MySQL 5.7) 或按天获取原始数据并使用 PHP?
计算连胜
您可以使用 MySQL 变量来计算连胜。基本上,当 isDone
为 1 时,您需要在连续的几天内增加连胜,并在 isDone
为 0 或日期不连续时重置它。此查询将生成每天的连续值:
SELECT s.Date,
@streak := IF(Date = @last_date + INTERVAL 1 DAY AND isDone = 1, @streak+1, 1) AS streak,
@last_date := Date AS last_date
FROM status s
JOIN (SELECT @streak := 0, @last_date := '1900-01-01') i
ORDER BY s.Date
输出:
Date streak last_date
2018-10-01 1 2018-10-01
2018-10-02 2 2018-10-02
2018-10-03 3 2018-10-03
2018-10-04 4 2018-10-04
2018-10-10 1 2018-10-10
2018-10-15 1 2018-10-15
2018-10-16 1 2018-10-16
2018-10-18 1 2018-10-18
2018-10-19 2 2018-10-19
2018-10-20 3 2018-10-20
然后您可以将其用作子查询来确定给定日期的连续记录,例如
SELECT Date, streak
FROM (SELECT s.Date,
@streak := IF(Date = @last_date + INTERVAL 1 DAY AND isDone = 1, @streak+1, 1) AS streak,
@last_date := Date AS last_date
FROM status s
JOIN (SELECT @streak := 0, @last_date := '1900-01-01') i
ORDER BY s.Date) s
WHERE s.Date = '2018-10-20'
输出:
Date streak
2018-10-20 3
我有以下 table :
Date | isDone
--------------------
2018-10-01 | 1
2018-10-02 | 1
2018-10-03 | 1
2018-10-04 | 1
2018-10-10 | 0
2018-10-15 | 1
2018-10-16 | 0
2018-10-18 | 1
2018-10-19 | 1
2018-10-20 | 1
每天只能有一行,有 2 个可能的值 0 或 1。一天不一定必须有一行。如果一天没有一行,则该值被视为 0。
我想计算 "current streak" 从当前日期开始完成的任务(isDone 列)。假设我们是 2018-10-20,结果将是 3。现在,我不想计算本月的最大连胜纪录,在本例中为 4(从 2018-10-01 到 2018-10-04)。我想知道计算这个的最佳选择是什么,直接使用 SQL (MySQL 5.7) 或按天获取原始数据并使用 PHP?
计算连胜您可以使用 MySQL 变量来计算连胜。基本上,当 isDone
为 1 时,您需要在连续的几天内增加连胜,并在 isDone
为 0 或日期不连续时重置它。此查询将生成每天的连续值:
SELECT s.Date,
@streak := IF(Date = @last_date + INTERVAL 1 DAY AND isDone = 1, @streak+1, 1) AS streak,
@last_date := Date AS last_date
FROM status s
JOIN (SELECT @streak := 0, @last_date := '1900-01-01') i
ORDER BY s.Date
输出:
Date streak last_date
2018-10-01 1 2018-10-01
2018-10-02 2 2018-10-02
2018-10-03 3 2018-10-03
2018-10-04 4 2018-10-04
2018-10-10 1 2018-10-10
2018-10-15 1 2018-10-15
2018-10-16 1 2018-10-16
2018-10-18 1 2018-10-18
2018-10-19 2 2018-10-19
2018-10-20 3 2018-10-20
然后您可以将其用作子查询来确定给定日期的连续记录,例如
SELECT Date, streak
FROM (SELECT s.Date,
@streak := IF(Date = @last_date + INTERVAL 1 DAY AND isDone = 1, @streak+1, 1) AS streak,
@last_date := Date AS last_date
FROM status s
JOIN (SELECT @streak := 0, @last_date := '1900-01-01') i
ORDER BY s.Date) s
WHERE s.Date = '2018-10-20'
输出:
Date streak
2018-10-20 3