2016-03-24 6 views
1
X Y 
------- 
A 1 
B 5 
C 9 

私は上記のデータのような結果セットを持っていて、基本的には以下のようなデータであるYのギャップに対応するレコードに対して、前のレコードのXの値を達成したいと考えています。これを達成するためのさまざまな方法は何ですか?どのように再帰で連続シーケンスのギャップを解決するには?

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

をお試しください定数。おそらく、SQLクエリの外に中間レコードを生成する必要があります。 – Dandorid

答えて

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 
2

SQLが離れてから、照会されたテーブルから出ていないコンテンツを生成することができないこの単純なクエリ、(@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