过滤我的SQL查询以搜索某个“顶级”父级的最佳方法是什么?

时间:2013-03-21 04:15:41

标签: sql nhibernate recursion

我有一个使用nhibernate的网站,它正在查询SQL服务器数据库。其中一个表格包含以下列:

ID
名称
的ParentId

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

Id名称ParentId
1,“乔”,3
3,“添”,5
5,“杰克”,7
7,“汤姆”,null

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

 "Select * from ThisTable where IsDescendant of 7"

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

在不必将所有内容保持在循环中的情况下,最好的方法是什么。此外,因为我使用nhibernate,我可以在我的代码中添加它作为一个函数,但它看起来像转换为数百个SQL语句。我也很好奇如何在原始SQL中执行此操作。

2 个答案:

答案 0 :(得分: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上的演示

答案 1 :(得分:0)

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

表XDescendance: ID,ItemID,ParentID,级别

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

然后你几乎可以像写它一样(几乎就是)

来查询
SELECT DISTINCT
        ThisTable.*
    FROM ThisTable
    INNER JOIN XDescendance
        ON ThisTable.ID = XDescendance.ItemID
        AND XDescendance.ParentID = 7