SQL 递归部分求和
Posted
技术标签:
【中文标题】SQL 递归部分求和【英文标题】:SQL Recursive partial sum 【发布时间】:2016-11-22 10:35:30 【问题描述】:我有两张桌子:
主表
...
startSubNr
endSubNr
...
步骤
...
nrFrom
nrTo
value
...
MasterTable 包含例如:
startSubNr: 2
endSubNr: 16
步骤包含例如:
nrFrom: 2
nrTo: 19
value: 20
nrFrom: 1
nrTo: 2
value: 10
nrFrom: 19
nrTo: 5
value: 100
nrFrom: 5
nrTo: 16
value: 200
nrFrom: 4
nrTo: 5
value: 50
我需要的是一个 sql 查询(它应该在 SQL-Server 和 sqlite 上工作)来计算从 startnr 到 endnr 的总和,其中步骤数可能会有所不同。步骤(从到到)是独一无二的。
在这个例子中,它必须总结 20 (2-19), 100 (19-5 em>) 和 200 (5-16),而忽略 1-2 和 4-5 的值。
有没有办法在 sql 中做到这一点而不必使用多个查询?
【问题讨论】:
为什么忽略其他两个值..? 因为在 Mastertable 中我有 startSubNr= 2 和 endSubNr= 16。在 Steps 表中,我搜索以 nrFrom 2 开头的步骤(nrTo 为 19,值为 20)。然后我搜索 nrFrom 19 的步骤(nrTo 为 5,值为 100),依此类推。我这样做直到达到 endNr 16 的 Step 并总结所有步骤的值。 【参考方案1】: CREATE TABLE #Steps(nrFrom INT,nrTo INT ,value INT) DECLARE @Start INT = 2,@End INT = 16
INSERT INTO #Steps(nrFrom ,nrTo ,value ) SELECT 2,19,20 UNION ALL SELECT 1,2,10 UNION ALL SELECT 19,5,100 UNION ALL SELECT 5,16,200 UNION ALL SELECT 4,5,50
;WITH _SumCTE (_From , _To , _Value )AS ( SELECT nrFrom ,nrTo,value FROM #Steps WHERE nrFrom = @Start UNION ALL SELECT _To , nrTo , value FROM #Steps JOIN _SumCTE ON _To = nrFrom and nrTo != @End
)
SELECT SUM(_Value) FROM _SumCTE
【讨论】:
这不处理终点 - 如果您将 UNION ALL SELECT 16,4,500 添加到您的数据中,它会以最大递归方式爆炸 检查到底是不是真的不见了。否则它工作正常。谢谢!【参考方案2】:这个递归查询做你想做的事,但有一些附加条件
如果无法到达所需的端点(例如 @end 为 1000),它将引发最大递归错误 它假定 nrFrom 是唯一的;如果给定的 nrFrom 有多个“路径”,你会得到奇怪的结果 循环路径会导致最大递归错误 sql 可能不是做这个逻辑的地方!创建表#step(nrFrom int, nrTo int, value int);
insert into #step values(2,19,20);
insert into #step values(1,2,10);
insert into #step values(19,5,100);
insert into #step values(5,16,200);
insert into #step values(4,5,50);
insert into #step values(16,4,500); -- add this to check we dont go further once we reach 16
declare @start int = 2;
declare @end int = 16;
with cte(nrTo, val) as
(
select nrTo, value
from #step
where nrFrom = @start
union all
select #step.nrTo, value
from cte
inner join #step on #step.nrFrom = cte.nrTo
and #step.nrFrom != @end
)
select sum(val)
from cte
【讨论】:
需要关卡吗?您只需要终点的值。以上是关于SQL 递归部分求和的主要内容,如果未能解决你的问题,请参考以下文章