Вычислять последовательные дневные полосы с MySQL - PullRequest
0 голосов
/ 20 октября 2018

У меня есть следующая таблица:

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

Может быть только одна строка в день с двумя возможными значениями 0 или 1. Для дня необязательно иметь строку.Если для дня нет строки, значение считается равным 0.

Я хочу вычислить «текущую серию» выполненных задач (столбец isDone) по текущей дате.Предположим, что мы 2018-10-20, результат будет 3 .На данный момент я не хочу вычислять самую большую полосу месяца, которая была бы в этом случае 4 (с 2018-10-01 по 2018-10-04).Мне интересно, каков наилучший вариант для вычисления этого непосредственно с помощью SQL (MySQL 5.7) или получения необработанных данных за день и вычисления полосы с помощью PHP?

1 Ответ

0 голосов
/ 21 октября 2018

Вы можете использовать переменные 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

Демонстрация на dbfiddle

...