1

我有一个使用 nhibernate 查询 SQL 服务器数据库的网站。其中一张表具有以下列:

ID
名称
ParentId

因此,此表中的某些条目可能是:

Id 名称 ParentId
1, "Joe", 3
3, "Tim", 5
5, "Jack", 7
7, "Tom", null

我正在尝试运行这样的查询(伪 SQL)。.

 "Select * from ThisTable where IsDescendant of 7"

这将返回任何 7 岁的孩子或孩子的孩子等。. (在上面的示例中,将返回所有行)

什么是解决这个问题的最佳方法,而不必将所有内容都保持在循环中。此外,由于我使用的是 nhibernate,因此我可以将其作为函数添加到我的代码中,但看起来它可以转换为数百条 SQL 语句。我也很好奇如何在原始 SQL 中做到这一点。

4

2 回答 2

0

我建议您创建一个表格,将计算出的后代保存在您所引用的表格中的所有条目的多个级别。使用 CTE 应该非常有效,但是如果您经常查询后代,如果您将所有后代数据写入一个具有如下结构的单独表中,则可以大大减少数据库开销:

表 XDescendance:ID、ItemID、ParentID、Level

然后,当该表上的触发器注意到任何更改时,您将重写此数据。

然后你可以几乎完全按照你写的那样查询它(几乎)

SELECT DISTINCT
        ThisTable.*
    FROM ThisTable
    INNER JOIN XDescendance
        ON ThisTable.ID = XDescendance.ItemID
        AND XDescendance.ParentID = 7
于 2013-03-21T08:37:44.933 回答
0

在 SQLServer2005+ 中,您可以使用递归 CTE

DECLARE @Id int = 7     
;WITH cte AS
  (
   SELECT Id, Name, ParentId
   FROM dbo.test45
   WHERE Id = @Id
   UNION ALL
   SELECT t.Id, t.Name, t.ParentId
   FROM dbo.test45 t JOIN cte c On t.ParentId = c.Id
   )
   SELECT *
   FROM cte

SQLFiddle上的演示

于 2013-03-21T08:30:48.033 回答