SQL Server计算基于递归CTE内的聚合

时间:2016-06-24 12:11:31

标签: sql-server recursion sql-server-2012 common-table-expression

你能帮我解决一下这个dillema吗?

我试图尽可能地简化示例,但基本上,我想要的是以某种方式在递归查询的下一级内使用递归查询的先前结果的聚合(希望这是有意义的)。 我尝试使用窗口函数(max()over()),但是出于某种原因,这些似乎只关注当前行(这里似乎有更好的解释:recursive cte with ranking functions)。 我也尝试不止一次引用'r'CTE,但这似乎是非法的。 您对我如何做到这一点还有其他想法吗?

我需要在SQL而不是T-SQL中执行此操作。原因是我实际上在T-SQL中使用循环有一个工作版本,但是对于我正在尝试做的事情来说,性能非常差。我希望纯SQL解决方案能更快地运行。

我正在使用SQL Server 2012。

谢谢!

- 这是有效的,但它不是递归的,我事先并不知道会有多少“级别”:

;with t as (
    select 1 a, 1 b union all
    select 2 a, 1 b union all
    select 3 a, 1 b
), r as (
    select a, b, 1 lvl
    from t
)
select *
from r
    union all --we took the "union all" outside the CTE, which means it's not recursive anymore
    select a + max(a) over(partition by b) a, --this now works as expected and returns "a + 3" on all cases
        b, lvl-1
    from r
    where lvl > 0

- 这不起作用:

;with t as (
    select 1 a, 1 b union all
    select 2 a, 1 b union all
    select 3 a, 1 b
), r as (
    select a, b, 1 lvl
    from t
    union all
    select a + max(a) over(partition by b) a, --this returns the "max" over only the current row instead of doing the partition from what I expect to be the "previous step"
        b, lvl-1
    from r
    where lvl > 0
)
select *
from r

- 这也失败了:

;with t as (
    select 1 a, 1 b union all
    select 2 a, 1 b union all
    select 3 a, 1 b
), r as (
    select a, b, 1 lvl
    from t
    union all
    select a + (select max(a) from r r2 where r2.b = r.b) a, --this returns the "max" over only the current row instead of doing the partition from what I expect to be the "previous step"
        b, lvl-1
    from r
    where lvl > 0
)
select *
from r

0 个答案:

没有答案