获取给定节点下的节点?

时间:2013-02-27 19:24:40

标签: sql sql-server-2008 graph

给定一个源节点,我想让所有节点“在”它下面,这意味着所有节点的级别小于给定节点的级别并且可以从给定节点到达。我记得这可以使用常见的表表达式完成,目前正在处理它。但是,有没有办法在大型图表(由大约100K节点组成)上快速完成此操作?

示例数据:

CREATE TABLE #TEMP(Source VARCHAR(50), SourceLevel INT, Sink VARCHAR(50), SinkLevel INT);


INSERT INTO #TEMP VALUES('A', 1, 'B', 2);
INSERT INTO #TEMP VALUES('A', 1, 'C', 2);
INSERT INTO #TEMP VALUES('B', 2, 'C', 2);
INSERT INTO #TEMP VALUES('B', 2, 'D', 3);
INSERT INTO #TEMP VALUES('B', 2, 'E', 3);
INSERT INTO #TEMP VALUES('C', 2, 'D', 3);
INSERT INTO #TEMP VALUES('C', 2, 'F', 3);
INSERT INTO #TEMP VALUES('C', 2, 'G', 3);


SELECT *
FROM #TEMP

GO

DROP TABLE #TEMP
GO

图形:

      A                        Level - 1
     / \
    B---C                      Level - 2
   / \ /|\
  E   D F G                    Level - 3

示例:

  • 鉴于B,我想得到:E,D
  • 鉴于A,我想得到:B,C,E,D,F,G
  • 鉴于C,我想得到:D,F,G

1 个答案:

答案 0 :(得分:1)

这里有一个可能的解决方案,使用Recursive CTEs,但是仍然存在一些问题(答案尚不完全匹配,但它到达那里)。一旦我接近我的最终要求,我就会更新这个查询。

编辑1 :以下所有输出除了请求根节点“A”的输出外,在这种情况下,由于某种原因,它只有一个深度。

编辑2 :这会给出预期的输出。我现在会查看其他用例。

;WITH HIERARCHY AS (
  SELECT T.Source, T.SourceLevel, T.Sink, T.SinkLevel
    FROM #TEMP T
   WHERE T.Source = 'A'
   AND T.SourceLevel < T.SinkLevel
 UNION ALL
 SELECT X.Source, X.SourceLevel, X.Sink, X.SinkLevel
   FROM #TEMP X
   JOIN HIERARCHY H ON H.Sink = X.Source
)
SELECT DISTINCT H.Sink
  FROM HIERARCHY H