2011-05-13 11 views
3

这是来自作业问题。我们通过动态构建SQL查询来解决这个问题。但是如果可以用纯SQL来处理,我们很感兴趣。查找一定深度的所有链接

简化想要的内容: 有一个包含两列的表:源ID和目标ID。给定一个ID和一个数字n,我们需要找到距离给定ID的距离为的所有ID等于

说明性编辑:
认为表格代表网络链接。如果表(1,3)出现在表格中,则表示网页1有链接到网页3的链接。
我们需要找到所有可从初始网页访问的网页,只需点击n次或减。

由于这是一个“好奇心”问题,请使用您喜欢的任何SQL实现。 “纯SQL”意味着符合“结构化查询风格”的所有内容。使用循环不被认为是“纯粹的SQL”(为了这个问题)。

+3

你的问题不是很清楚。来自给定ID的距离n的所有id是什么意思?你的桌子代表某种树吗?你能否举一个这样的表格,举例说明样本数据清楚地表明“N深”的含义? –

+0

...你是什么意思纯粹的SQL? –

+1

...你用什么dbms? –

回答

1

使用关系代数或纯老SQL不能表达transitive closure,所以对于任意N型的通用解决方案是不可能

您可以做的最好的方法是在“编译时”选择N,并使用大量的连接,就像您在动态生成的查询方法中所做的那样。

1

简短的回答是,对于任何“n”它可能不可能通过香草SQL。你试图做的是在广度上探索所有的链接直到给定的深度“n”。

1

在MS SQL 2005+可以使用递归查询

;WITH RecursiveTbl AS 
(
    SELECT WL.SouriceID, WL.DestinationId, 0 AS level 
    FROM WEBLINKS WL 
    WHERE WL.SouriceID = @your_top_level_id 

    UNION ALL 

    SELECT WL.SouriceID, WL.DestinationId, RWL.level + 1 AS level 
    FROM RecursiveTbl RWL 
    JOIN WEBLINKS WL ON RWL.DestinationId = WL.SourceID 
) 
SELECT * FROM RecursiveTbl WHERE level BETWEEN 1 AND 3; 

查询最初用相同的SourceID选择记录,然后递归加入到自身。

之后,就像过滤掉所有不需要的记录一样简单。