2016-03-24 5 views
1

Ich habe ein Ergebnis wie die obigen Daten festgelegt und möchte den Wert von X für den vorherigen Datensatz zu den Datensätzen entsprechend den Lücken in Y, die im Grunde ist etwas, das wie folgt aussieht Daten zu erreichen. Was sind die verschiedenen Wege, dies zu erreichen?Wie Lücken in der Kontinuitätssequenz mit Rekursion zu lösen?

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

SQL kann keine Inhalte generieren, die nicht von der Tabelle nicht herauskommt, die abgefragt wird, abgesehen von Konstanten. Wahrscheinlich müssen Sie die Zwischensätze außerhalb Ihrer SQL-Abfrage generieren. – Dandorid

Antwort

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

Versuchen Sie diese einfache Abfrage (nehmen @tbl ist Ihre Tabelle/Ergebnismenge)

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