使用 SUM 进行递归连接
Recursive join with SUM
我有以下格式的数据:
FromStateID ToStateID Seconds
1 2 10
2 3 20
3 4 15
4 5 5
我需要以下输出
FromStateID ToStateID Seconds
1 2 10
2 3 20
3 4 15
4 5 5
1 3 10+20
1 4 10+20+15
1 5 10+20+15+5
2 4 20+15
2 5 20+15+5
3 5 15+5
此输出显示按时间顺序排列的每个组合所花费的总时间 FromStateId
到 ToStateId
。
请帮忙。
我认为这是一个遵循链接的递归 CTE:
with cte as (
select FromStateID, ToStateID, Seconds
from t
union all
select cte.FromStateId, t.ToStateId, cte.Seconds + t.Seconds
from cte join
t
on cte.toStateId = t.FromStateId
)
select *
from cte;
Here 是一个 db<>fiddle.
@Gordon LinOff 是更好的解决方案。下面是实现相同目的的另一种选择。
您可以使用 CROSS JOIN 和 GROUP BY 实现此目的
DECLARE @table table(FromStateId int, ToStateId int, seconds int)
insert into @table
values
(1 ,2 ,10),
(2 ,3 ,20),
(3 ,4 ,15),
(4 ,5 ,5 );
;with cte_fromToCombination as
(select f.fromStateId, t.tostateId
from
(select distinct fromStateId from @table) as f
cross join
(select distinct toStateId from @table) as t
)
select c.FromStateId, c.ToStateId, t.sumseconds as Total_seconds
from cte_fromToCombination as c
CROSS APPLY
(SELECT sum(t.seconds)
from
@table as t
WHERE t.ToStateId <= c.ToStateId
) as t(sumseconds)
where c.tostateId > c.fromStateId
order by FromStateId,ToStateId
+-------------+-----------+---------------+
| FromStateId | ToStateId | Total_seconds |
+-------------+-----------+---------------+
| 1 | 2 | 10 |
| 1 | 3 | 30 |
| 1 | 4 | 45 |
| 1 | 5 | 50 |
| 2 | 3 | 30 |
| 2 | 4 | 45 |
| 2 | 5 | 50 |
| 3 | 4 | 45 |
| 3 | 5 | 50 |
| 4 | 5 | 50 |
+-------------+-----------+---------------+
我有以下格式的数据:
FromStateID ToStateID Seconds
1 2 10
2 3 20
3 4 15
4 5 5
我需要以下输出
FromStateID ToStateID Seconds
1 2 10
2 3 20
3 4 15
4 5 5
1 3 10+20
1 4 10+20+15
1 5 10+20+15+5
2 4 20+15
2 5 20+15+5
3 5 15+5
此输出显示按时间顺序排列的每个组合所花费的总时间 FromStateId
到 ToStateId
。
请帮忙。
我认为这是一个遵循链接的递归 CTE:
with cte as (
select FromStateID, ToStateID, Seconds
from t
union all
select cte.FromStateId, t.ToStateId, cte.Seconds + t.Seconds
from cte join
t
on cte.toStateId = t.FromStateId
)
select *
from cte;
Here 是一个 db<>fiddle.
@Gordon LinOff 是更好的解决方案。下面是实现相同目的的另一种选择。
您可以使用 CROSS JOIN 和 GROUP BY 实现此目的
DECLARE @table table(FromStateId int, ToStateId int, seconds int)
insert into @table
values
(1 ,2 ,10),
(2 ,3 ,20),
(3 ,4 ,15),
(4 ,5 ,5 );
;with cte_fromToCombination as
(select f.fromStateId, t.tostateId
from
(select distinct fromStateId from @table) as f
cross join
(select distinct toStateId from @table) as t
)
select c.FromStateId, c.ToStateId, t.sumseconds as Total_seconds
from cte_fromToCombination as c
CROSS APPLY
(SELECT sum(t.seconds)
from
@table as t
WHERE t.ToStateId <= c.ToStateId
) as t(sumseconds)
where c.tostateId > c.fromStateId
order by FromStateId,ToStateId
+-------------+-----------+---------------+
| FromStateId | ToStateId | Total_seconds |
+-------------+-----------+---------------+
| 1 | 2 | 10 |
| 1 | 3 | 30 |
| 1 | 4 | 45 |
| 1 | 5 | 50 |
| 2 | 3 | 30 |
| 2 | 4 | 45 |
| 2 | 5 | 50 |
| 3 | 4 | 45 |
| 3 | 5 | 50 |
| 4 | 5 | 50 |
+-------------+-----------+---------------+