数据
我有以下部分数据
id parent multiplier const
-- ------ ---------- -----
1 NULL 1.10 1.00
2 1 1.20 2.00
3 1 1.30 3.00
4 1 2.40 4.00
5 2 2.50 5.00
6 2 2.60 6.00
7 2 2.70 17.00
8 3 2.80 18.00
9 3 3.90 19.00
10 3 3.10 7.00
11 8 3.20 8.00
12 8 3.30 9.00
13 8 3.40 10.00
14 9 4.50 11.00
15 10 4.60 21.00
15 10 4.70 22.00
可以在树中显示如下
1
+-- 2
| +-- 5
| +-- 6
| +-- 7
|
+-- 3
| +-- 8
| | +-- 11
| | +-- 12
| | +-- 13
| |
| +-- 9
| | +-- 14
| |
| +-- 10
| +-- 15
| +-- 16
|
+-- 4
用于创建表结构和数据的SQL
DECLARE @table TABLE (Id int, Parent int, multiplier decimal(6,3), Const decimal(6,3));
INSERT INTO @table
SELECT 1, NULL, 1.1, 1.00 UNION
SELECT 2, 1, 1.2, 2.00 UNION
SELECT 3, 1, 1.3, 3.00 UNION
SELECT 4, 1, 2.4, 4.00 UNION
SELECT 5, 2, 2.5, 5.00 UNION
SELECT 6, 2, 2.6, 6.00 UNION
SELECT 7, 2, 2.7, 17.00 UNION
SELECT 8, 3, 2.8, 18.00 UNION
SELECT 9, 3, 3.9, 19.00 UNION
SELECT 10, 3, 3.1, 7.00 UNION
SELECT 11, 8, 3.2, 8.00 UNION
SELECT 12, 8, 3.3, 9.00 UNION
SELECT 13, 8, 3.4, 10.00 UNION
SELECT 14, 9, 4.5, 11.00 UNION
SELECT 15, 10, 4.6, 21.00 UNION
SELECT 15, 10, 4.7, 22.00;
问题
我需要为树中任何节点的根计算递归aX+b
公式。换句话说,我需要计算子节点的公式,并将结果值移到父级x
并继续计算,直到我到达root。
例如,为x=1250.00
计算node 14
将是
1.10 * (1.30 *( 3.90 * (4.50 * 1250.00 + 11.00) + 19.00) + 3.00) + 1.00 = 31463.442
目前我正在使用CTE树和C#进行此操作,但我对其速度和优化不满意。
问题
我可以在SQL服务器上进行此计算,只返回值吗?如果可能,我可以使用CTE导航的树深度是多少?
答案 0 :(得分:1)
我可以在SQL服务器上进行此计算,只返回值吗?
是的,从叶节点执行递归,随时进行计算并在主查询中获取最大值。
with C as
(
select T.Id,
T.Parent,
cast(T.multiplier * @x + T.Const as decimal(19, 3)) as x
from @table as T
where T.Id = 14
union all
select T.Id,
T.Parent,
cast(T.multiplier * C.x + T.Const as decimal(19, 3))
from C
inner join @table as T
on C.Parent = T.Id
)
select max(C.x) as Value
from C
option (maxrecursion 0);
如果可能,我可以导航的树深度是多少 CTE?
默认值为100,但您可以使用maxrecursion
进行更改。使用option (maxrecursion 0)
时没有限制。
我对它的速度和优化感到不满意。
要解决这个问题,你必须展示你实际做的事情。如果您在Id
上拥有群集主键,则您提供的示例会获得一个好的计划。
它寻求找到锚点并寻找每次迭代。