如何在 SQL 中满足条件之前对行求和

How to sum rows before a condition is met in SQL

我有一个 table,它有同一个 ID 的多条记录。看起来像这样,行按序号排序。

+----+--------+----------+----------+
| id | result | duration | sequence |
+----+--------+----------+----------+
| 1  | 12     | 7254     | 1        |
+----+--------+----------+----------+
| 1  | 12     | 2333     | 2        |
+----+--------+----------+----------+
| 1  | 11     | 1000     | 3        |
+----+--------+----------+----------+
| 1  | 6      | 5        | 4        |
+----+--------+----------+----------+
| 1  | 3      | 20       | 5        |
+----+--------+----------+----------+
| 2  | 1      | 230      | 1        |
+----+--------+----------+----------+
| 2  | 9      | 10       | 2        |
+----+--------+----------+----------+
| 2  | 6      | 0        | 3        |
+----+--------+----------+----------+
| 2  | 1      | 5        | 4        |
+----+--------+----------+----------+
| 2  | 12     | 3        | 5        |
+----+--------+----------+----------+

例如对于 id=1,我想将之前所有行的持续时间相加并包括 result=6,即 7254+2333+1000+5id =2 也是如此,它将是 230+10+0result=6 所在行之后的任何内容都将被忽略。

我的预期输出:

+----+----------+
| id | duration |
+----+----------+
| 1  | 10592    |
+----+----------+
| 2  | 240      |
+----+----------+

序列必须按升序排列。

我不确定如何在 sql 中执行此操作。 提前致谢!

基本分组查询应该可以解决您的问题

select 
  id,
  sum(duration) duration
from t
group by id

对于某些行:

select 
  id,
  sum(duration) duration
from t
where id = 1
group by id

如果您想将其包含在结果集中

select id, duration, sequence from t 
union all
select 
  id,
  sum(duration) duration
  null sequence
from t
group by id

您可以使用一个简单的聚合查询,条件是使用子查询来恢复与序列为 6 的记录对应的 sequence :

SELECT t.id, SUM(t.duration) total_duration
FROM mytable t
WHERE t.sequence <= (
    SELECT sequence
    FROM mytable
    WHERE id = t.id AND result = 6
)
GROUP BY t.id

这个demo on DB Fiddle加上你的测试数据returns:

| id  | total_duration |
| --- | -------------- |
| 1   | 10592          |
| 2   | 240            |

我想你想要:

select t2.id, sum(t2.duration)
from t
where t.sequence <= (select t2.sequence
                     from t t2
                     where t2.id = t.id and t2.result = 6
                    );

在 PrestoDB 中,我会推荐 window 个函数:

select id, sum(duration)
from (select t.*,
             min(case when result = 6 then sequence end) over (partition by id) as sequence_6
      from t
     ) t
where sequence <= sequence_6;