如何用递归解决连续序列中的空白?

时间:2016-03-24 07:17:05

标签: sql sql-server

 X  Y
-------
 A  1
 B  5
 C  9

我有一个像上面数据一样的结果集,并希望将前一个记录的X值实现到与Y中的间隙相对应的记录,这基本上类似于下面的数据。有哪些不同的方法来实现这一目标?

X   Y
-------
 A  1
 A  2
 A  3
 A  4
 B  5
 B  6
 B  7
 B  8
 C  9

2 个答案:

答案 0 :(得分:3)

declare @tbl table
(
    X   char,
    Y   int
)

insert into @tbl select 'A', 1
insert into @tbl select 'B', 5
insert into @tbl select 'C', 9

-- Query 1 : recursive CTE 
; with 
cte as
(
    select  rn = ROW_NUMBER() over (order by Y), X, Y
    from    @tbl
),
rcte as
(
    select  rn, X, Y 
    from    cte 
    where   rn  = 1

    union all

    select  rn  = case when r.Y + 1 < c.Y then r.rn else c.rn end, 
        X   = case when r.Y + 1 < c.Y then r.X else c.X end, 
        Y   = case when r.Y + 1 < c.Y then r.Y + 1 else c.Y end
    from    rcte r
        inner join cte c    on  r.rn = c.rn - 1
)
select  *
from    rcte

-- Query 2 : tally table method. Required SQL Server 2012+

; with tally as
(
    select  n = 1
    union all
    select  n = n + 1
    from    tally
    where   n <= 100
),
cte as
(   select  *, next_Y = isnull(LEAD(Y) OVER (ORDER BY Y), Y + 1)
    from    @tbl t
)
select  c.X, n.n as Y
from    cte c
    cross join tally n
where   n.n >= c.Y
and n.n < c.next_Y

答案 1 :(得分:2)

尝试这个简单的查询,(假设@tbl是你的表/结果集)

WITH cte_test
AS
(
    SELECT t.X,t.Y,isnull((SELECT min(t1.Y) FROM @tbl t1 WHERE t1.X > t.X),t.Y) AS maxval FROM @tbl t
    UNION ALL
    SELECT t.X,c.Y+1,c.maxval FROM cte_test c
    INNER JOIN @tbl t ON c.X = t.X
    WHERE c.Y+1 < c.maxval
)
SELECT X,Y FROM cte_test ORDER BY 1,2