MySQL - вычислить накопление с момента сброса в таблице - PullRequest
0 голосов
/ 16 января 2019

Этот вопрос является справочным для моего другого вопроса

Решение Python было сделано на основе извлечения из базы данных MySQL (5.6.34), где хранятся исходные данные. Мой вопрос: возможно ли сделать такой расчет прямо в MySQL?

Просто чтобы напомнить: Есть таблица «бегунов» с накопленной дистанцией на каждого бегуна и метками сброса

    runner  startdate   cum_distance    reset_event
0   1       2017-04-01  100             1           
1   1       2018-04-20  125             0           
2   1       2018-05-25  130             1           
3   2       2015-04-05  10              1           
4   2       2015-10-20  20              1           
5   2       2016-11-29  50              0         

Я хотел бы рассчитать накопленную дистанцию ​​для каждого бегуна с момента сброса (мои комментарии в скобках ()):

    runner  startdate   cum_distance    reset_event runner_dist_since_reset
0   1       2017-04-01  100             1           100     <-(no reset since begin)
1   1       2018-04-20  125             0           25      <-(125-100)
2   1       2018-05-25  130             1           30      <-(130-100)
3   2       2015-04-05  10              1           10      <-(no reset since begin)
4   2       2015-10-20  20              1           10      <-(20-10)
5   2       2016-11-29  50              0           30      <-(50-20)

Пока мне удалось вычислить только различия между событиями сброса:

SET @DistSinceReset=0;

SELECT
runner,
startdate,
reset_event,
IF(cum_distance - @DistSinceReset <0, cum_distance, cum_distance - @DistSinceReset) AS 'runner_dist_since_reset',
@DistSinceReset := cum_distance AS 'cum_distance'
FROM
runners
WHERE  
reset_event = 1
GROUP BY runner, startdate

1 Ответ

0 голосов
/ 16 января 2019

Этот ответ для MySQL 8.

Требуемая информация является самой последней cum_distance для каждого пользователя с reset_event = 1. Вы используете MySQL 8, поэтому вы можете использовать оконные функции.

Вот один из методов:

select r.*,
       (cum_distance - coalesce(preceding_reset_cum_distance, 0)) as runner_dist_since_reset
from (select r.*,
             min(cum_distance) over (partition by runner order by preceding_reset) as preceding_reset_cum_distance
      from (select r.*,
                   max(case when reset_event = 1 then start_date end) over
                       (partition by runner
                        order by start_date
                        rows between unbounded preceding and 1 preceding
                       ) as preceding_reset
            from runners r
           ) r
     ) r;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...