MySQL-计算自表中的重置事件以来的累积

时间:2019-01-16 08:52:06

标签: mysql sql

此问题是我的other question

的参考

Python解决方案基于存储原始数据的MySQL DB(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 :(得分:0)

此答案适用于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;