总和直到某个值

时间:2017-10-26 18:08:46

标签: mysql group-by sum

我已经为此尝试了一些其他主题,但无法得到实际适用于我的答案。 我有一个带有一些值的活动表(在mysql中)

| id| user_id    |      elevation     | distance |
|---|------------|--------------------|----------|
| 1 | 1          | 220                | 5000     |
| 2 | 1          | 300                | 7000     |
| 3 | 2          | 520                | 2000     |
| 4 | 2          | 120                | 3500     |

我需要将距离和海拔相加,直到距离总和达到某个值,每个user_id。

示例,达到5000之前的总和:

  • 用户1 - 距离5000 - 海拔220
  • 用户2 - 距离5500 - 海拔640

我找到了很多解决方案但没有找到group_by。我是怎么用mysql做的?

更新:我使用了该查询,但现在我遇到了另一个问题。连接始终使用插入顺序,而不是我想要的日期时间字段。

SELECT
t.*
FROM
(
    SELECT
        t.*,
        (
            @d := @d + DISTANCE


        ) AS running_distance
    FROM
        (
            SELECT
                t.*,
                c.meta
            FROM
                inscricao i
            INNER JOIN categorias c ON
                i.categoria_id = c.id
            LEFT JOIN(
                    select
                        t.data_inicio,t.usuario_id,t.aplicativo,t.data_fim,t.distance,t.tempo_decorrido,t.ritmo_cardiaco,t.velocidade_media,t.type,t.ganho_de_altimetria
                    from
                        corridas t
                    order by
                        data_inicio asc
                ) t ON
                t.usuario_id = i.usuario_id
                AND t.data_inicio >= i.inicio
                AND t.data_fim <= i.fim
            WHERE
                i.desafio_id = 29
                AND(
                    i.usuario_id = 5354
                )
            ORDER BY
                data_inicio asc
                -- usuario_id
        ) t 
     join (
            SELECT
                @u :=- 1,
                @d := 0
        ) params
        ORDER BY
                data_inicio asc
) t 
WHERE
(
    running_distance >= meta * 1000
    AND running_distance - DISTANCE < meta * 1000
)
OR(
    running_distance <= meta * 1000
)
order by
data_inicio desc

因此,如果之后插入较旧的活动,则总和会出错。有人知道如何处理它吗?

1 个答案:

答案 0 :(得分:1)

您可以使用变量来获取累积总和。 。 。然后是一些简单的过滤逻辑:

select t.*
from (select t.*,
             (@d := if(@u = user_id, @d + distance,
                       if(@u := user_id, distance, distance)
                      )
             ) as running_distance  -- pun intended ??
      from (select t.*
            from t
            order by user_id, id
           ) t cross join
           (select @u := -1, @d := 0) params
     ) t
where running_distance >= 5000 and
      running_distance - distance < 5000;

注意:

  • 最新版本的MySQL对变量赋值和order by非常挑剔。早期版本的MySQL中不需要最里面的子查询。
  • MySQL不保证select中表达式的评估顺序。因此,所有变量赋值都在一个表达式中。
  • 如果距离可以是负数,则用户可能在结果集中有多行。
  • 这不是聚合查询。