2014-05-07 74 views
-4

我有這樣的一個表:SQL數據綜述

Name | FromPoint | TOPoint 
-------------------------- 
A | 0  | 2 
A | 2  | 4 
B | 2  | 4 
A | 4  | 9 
B | 5  | 6 

我怎麼能寫在T-SQL查詢,以平等遞歸加入域FromPoint和尖山每一個組合名稱/ FromPoint? 一個例子最終想要的結果的(以上數據考慮)是:

Name | FromPoint | ToPoint 
---------------------------- 
A | 0  | 9 
B | 2  | 4 
B | 5  | 6 
+0

第2行和第3行發生了什麼?如果A 0 9 B 2 6 ?? –

+0

是否有每個名稱的最大數量從/到?如在0-2-4-9中可以進一步擴展到例如0-2-4-9-11-13-22 –

+0

Brett Schneider是的,我有一個巨大的數據 –

回答

2

我們e一個遞歸的cte,從一個元素開始,這些元素的frompoint在自連接中與nopoint不匹配,以便識別出發點。然後通過再次連接來重新獲得中間結果,並且只使用那些在另一個自我連接中不與frompoint匹配的數據。

with cte as (
    select r.name, r.frompoint, r.topoint 
     from #t l 
    right join 
      #t r 
     on l.topoint = r.frompoint 
     and l.name = r.name 
    where l.name is null 
    union all 
    select l.name, l.frompoint, r.topoint 
     from cte l 
     join #t r 
     on l.topoint = r.frompoint 
     and l.name = r.name 
) 
select l.* 
    from cte l 
    left join 
     #t r 
    on r.name = l.name 
    and r.frompoint = l.topoint 
where r.name is null 
0

不是一個完整的答案,但一開始
我認爲這會產生結束點

select left.Name, left.ToPoint 
    from table left 
    left join table right 
    on left.name = right.name 
    on left.ToPoint = right.FromPoint 
where right.FromPoint is null 

走回去的開始認爲將需要一個遞歸CTE
問題是,你可以有序列裏面像A 1 3這樣排序不會分組序列

+0

謝謝你擴展huMpty duMpty評論 – vav

0

另一個不使用遞歸的選項。它使用內存中的表來編號(Num字段)不同的段。然後它爲每個細分市場的所有成員編號。最後,它按名稱在每個分段上分組,並且Num提供FromPoint的最小值和ToPoint的最大值。

只有組內沒有重疊分段時,這才起作用。

DECLARE @tbl TABLE(Num INT, Name VARCHAR(50), FromPoint INT, ToPoint INT) 
INSERT INTO @tbl 
    SELECT ROW_NUMBER() OVER (ORDER BY T.Name, T.FromPoint)Num 
     , T.Name, T.FromPoint, T.ToPoint 
    FROM TestTable T 
    WHERE NOT EXISTS(SELECT T.Name FROM TestTable T1 
          WHERE T.Name=T1.Name AND T.FromPoint=T1.ToPoint) 
    UNION 
    SELECT 0 Num, T2.Name, T2.FromPoint, T2.ToPoint 
    FROM TestTable T2 
    WHERE EXISTS(SELECT T3.Name FROM TestTable T3 
       WHERE T2.Name=T3.Name AND T2.FromPoint=T3.ToPoint) 

SELECT MyTable.Name, MIN(MyTable.FromPoint)FromPoint, MAX(MyTable.ToPoint)ToPoint 
FROM 
(SELECT CASE WHEN T.Num=0 THEN 
    (SELECT TOP 1 TMP.Num FROM @tbl TMP WHERE TMP.Name=T.Name 
      AND T.FromPoint>TMP.FromPoint AND TMP.Num>0 
    ORDER BY T.FromPoint-TMP.FromPoint 
       ) 
    ELSE T.Num END Num 
    ,T.Name, T.FromPoint, T.ToPoint FROM 
@tbl T)MyTable 
GROUP BY MyTable.Name, MyTable.Num 
+0

我覺得這個打破在序列中有一個序列。例如A 1 3 – Paparazzi

+0

@Blam Ya只有在組內沒有重疊片段的情況下才能使用。 –