用 CTE 树计算公式

Calculating Formula with CTE tree

数据

我有以下部分数据

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 创建 table 结构和数据

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 移动到父节点并继续计算直到我到达根节点。

例如,为 node 14 计算 x=1250.00 将是

1.10 * (1.30 *( 3.90 * (4.50 * 1250.00 + 11.00) + 19.00) + 3.00)  + 1.00 = 31463.442

目前我正在使用 CTE 树和 C# 执行此操作,但是我对其速度和优化不满意。

问题

我可以在 SQL 服务器上仅 return 计算值吗?如果可能的话,我可以使用 CTE 导航的树深度是多少?

Can I do this calculation on SQL server and just return the value?

是的,从叶节点开始递归,边走边计算,在主查询中取最大值。

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);

If it is possible, what is the tree depth that I can navigate with CTE?

默认值为 100,但您可以使用 maxrecursion 更改它。使用 option (maxrecursion 0) 时没有限制。

I am not satisfied with its speed and optimization.

要解决这个问题,您必须展示您的实际工作。如果您在 Id.

上有一个集群主键,您提供的示例将得到一个很好的计划

它会寻找定位点并在每次迭代中寻找。