У меня есть небольшая программа, которую я использую, чтобы отслеживать мои успехи в чтении книг и прочее, например goodreads, чтобы узнать, сколько я читаю за день.
Для этого я создал две таблицы: tbl_materials (material_id int, имя varchar), tbl_progress (временная метка date_of_update, внешний ключ material_id int, int read_pages, пропущенный бит).
Всякий раз, когда я читаю некоторые страницы, я вставляю в tbl_progress текущую страницу, которую я закончил
Я могу читать в книге несколько раз. И если я пропустил несколько страниц, я вставил их в tbl_progress и пометил бит skipped
как true. Проблема в том, что я не могу запросить tbl_progress, чтобы узнать, сколько я читаю за день
Я пытался найти последний вставленный прогресс для каждого отдельного материала в каждый день
так например:
+-------------+------------+---------+---------------------+
| material_id | read_pages | skipped | last_update |
+-------------+------------+---------+---------------------+
| 4 | 1 | | 2017-09-22 00:56:02 |
| 3 | 1 | | 2017-09-22 00:56:14 |
| 12 | 1 | | 2017-09-24 20:13:01 |
| 4 | 30 | | 2017-09-25 01:56:38 |
| 4 | 34 | | 2017-09-25 02:19:47 |
| 54 | 1 | | 2017-09-29 04:22:11 |
| 59 | 9 | | 2017-10-14 15:25:14 |
| 4 | 68 | T | 2017-10-18 02:33:04 |
| 4 | 72 | | 2017-10-18 03:50:51 |
| 2 | 3 | | 2017-10-18 15:02:46 |
| 2 | 5 | | 2017-10-18 15:10:46 |
| 4 | 82 | | 2017-10-18 16:18:03 |
| 4 | 84 | | 2017-10-20 18:06:40 |
| 4 | 87 | | 2017-10-20 19:11:07 |
| 4 | 103 | T | 2017-10-21 19:50:29 |
| 4 | 104 | | 2017-10-22 19:56:14 |
| 4 | 108 | | 2017-10-22 20:08:08 |
| 2 | 6 | | 2017-10-23 00:35:45 |
| 4 | 111 | | 2017-10-23 02:29:32 |
| 4 | 115 | | 2017-10-23 03:06:15 |
+-------------+------------+---------+---------------------+
Я вычисляю общее количество прочитанных страниц в день = последняя прочитанная страница в этот день - последняя прочитанная страница за дату до этой даты, и это работает, но проблема в том, что я не могу избежать пропущенных страниц.
первая строка в 2017-09-22 Я прочитал 1 страницу, затем еще 1 страницу, поэтому общее количество прочитанных в этот день = 2 (только для material_id = 4)
в 2017-09-25 последнее обновление для material_id 4 составляет 34 страницы, что означает, что я прочитал 34-1 = 33 страницы (последнее обновление в этот день 34 - последнее обновление до этой даты 1) = 33
до сих пор все работает хорошо, но когда дело доходит до рассмотрения пропущенных страниц, я не могу сделать это, например:
в 2017-10-18 последним числом прочитанных страниц для material_id = 4 было 34 (в 2017-09-25), затем я пропустил 34 страницы, и теперь текущая страница - 68, затем прочитал 4 страницы (2017-10-18 03: 50:51) затем еще 10 страниц (2017-10-18 16:18:03), поэтому общее значение для material_id = 4 равно 14
Я создал представление для выбора самой последней last_update для каждой книги в каждый день
create view v_mostRecentPerDay as
select material_id id,
(select title from materials where materials.material_id = id) title,
completed_pieces,
last_update,
date(last_update) dl,
skipped
from progresses
where last_update = (
select max(last_update)
from progresses s2
where s2.material_id = progresses.material_id
and date(s2.last_update) = date(progresses.last_update)
and s2.skipped = false
);
, так что если за одну книгу происходит много обновлений для одной книги, это представление извлекает последнюю (с максимальным значением last_update), которая сопровождает наибольшее количество прочитанных страниц и так для каждой отдельной книги
и другой вид, чтобы получить общее количество прочитанных страниц каждый день:
create view v_totalReadInDay as
select dl, sum(diff) totalReadsInThisDay
from (
select dl,
completed_pieces - ifnull((select completed_pieces
from progresses
where material_id = id
and date(progresses.last_update) < dl
ORDER BY last_update desc
limit 1
), 0) diff
from v_mostRecentPerDay
where skipped = false
) omda
group by dl;
но проблема в том, что при последнем просмотре вычисляются пропущенные страницы.
ожидаемый результат:
+------------+------------------+
| day | total_read_pages |
+------------+------------------+
| 2017-09-22 | 2 |
+------------+------------------+
| 2017-09-24 | 1 |
+------------+------------------+
| 2017-09-25 | 33 |
+------------+------------------+
| 2017-09-29 | 1 |
+------------+------------------+
| 2017-10-14 | 9 |
+------------+------------------+
| 2017-10-18 | 19 |
+------------+------------------+
| 2017-10-20 | 5 |
+------------+------------------+
| 2017-10-21 | 0 |
+------------+------------------+
| 2017-10-22 | 21 |
+------------+------------------+
| 2017-10-23 | 8 |
+------------+------------------+
mysql> SELECT VERSION();
+-----------------------------+
| VERSION() |
+-----------------------------+
| 5.7.26-0ubuntu0.16.04.1-log |
+-----------------------------+