2014-05-07 38 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只有在组内没有重叠片段的情况下才能使用。 –