以下模式的递归cte

时间:2018-02-07 02:36:25

标签: sql sql-server

输入:

col1 col2
1    val
2    Null
3    Null
4    val1
5    Null

输出:

col1 col2
1    val
2    val
3    val
4    val1
5    val1

概念:无论它在列中为null,它都应该搜索前一行以获取值而不是null,如果前一行为null则它应该搜索该行的前一行。就像不应该有任何null它将被值替换最新的以前的值.SQl服务器2012

2 个答案:

答案 0 :(得分:4)

您不需要递归CTE。一个简单的方法是:

select t.col1, tt.col2
from t outer apply
     (select top 1 col2
      from t t2
      where t2.col1 <= t1.col1 and t2.col2 is not null
      order by t2.col1 desc
     ) tt;

这是一个SQL小提琴(感谢John Woo)。

您可以通过ANSI标准lag(col2 ignore nulls) over (order by col1)获得所需的实际功能。但是,SQL Server不支持。

最有效的方法是使用窗口函数。我建议:

select col1, max(col2) over (partition by grp) as col2
from (select t.*,
             count(col2) over (order by col1) as grp
      from t
     ) t;

我非常确定这种方法比递归CTE更具可扩展性和更快。

答案 1 :(得分:3)

以下是使用recursive cte

的解决方案
with cte as (
    select
        *, rn = row_number() over (order by col1)
    from
        (values
            (1, 'val')
            ,(2 , Null)
            ,(3, Null)
            ,(4, 'val1')
            ,(5, Null)
        ) t(col1, col2)
)
, rcte as (
    select
        col1, col2, rn
    from
        cte
    union all
    select
        a.col1, b.col2, b.rn
    from
        rcte a
        join cte b on a.rn - 1 = b.rn
    where
        a.col2 is null
)
select col1, col2 from rcte
where col2 is not null
order by col1