查找一定深度的所有链接

发布于 2024-11-07 03:57:59 字数 371 浏览 0 评论 0原文

这是一个家庭作业问题。我们通过动态构建 SQL 查询来解决这个问题。但我们感兴趣的是是否可以使用纯 SQL 来完成。

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

澄清编辑:
将该表视为代表网络链接。如果表中出现行(1,3),则表示网页1有到网页3的链接。
我们需要找到从起始网页通过 n 次或更少的点击即可到达的所有网页。

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

This is from a homework question. We solved it by building the SQL query dynamically. But we are interested if it is possible to do with pure SQL.

A simplification of what is desired:
There is a table with two columns: source id and destination id. Given an id and a number n, we need to find all id of distance smaller equal n from the given id.

Clarification Edit:
Think about the table as representing web-links. If the row (1,3) appears in the table, it means that web-page 1 has a link to web-page 3.
We need to find all webpages that are reachable from a starting web-page with n clicks or less.

Since it is a "curiosity" question, use whatever SQL implementation you prefer.
"Pure SQL" means everything that fits into the "structured query style". Using loops is not considered "pure SQL" (for the sake of the question).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

椵侞 2024-11-14 03:57:59

您无法使用关系代数或纯旧 SQL 来表达传递闭包,因此对于任何N 是不可能

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

You cannot express transitive closure using relational algebra or pure old SQL, so a general solution for any N is not possible.

The best you can do is choose the N at "compile time" and use lots of joins, as you already do in the dynamically generated query approach.

时光病人 2024-11-14 03:57:59

简短的回答是,对于任何“n”,它可能无法通过普通 SQL 实现。您试图做的是探索所有链接的广度,直到给定的深度“n”。

The short answer is that for any "n" it might not be possible via vanilla SQL. What you are attempting to do is to explore all the links breadth wise until a given depth "n".

锦爱 2024-11-14 03:57:59

在 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 的记录,然后递归地连接到自身。

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

In MS SQL 2005+ you can use a recursive query

;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;

The query initially selects records with the same SourceID and then recursively join to itself.

After that, it's as simple as filtering out all the records that you don't need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文