如何在 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+5
。 id =2
也是如此,它将是 230+10+0
。 result=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;
我有一个 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+5
。 id =2
也是如此,它将是 230+10+0
。 result=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;