我有一个使用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中执行此操作。
答案 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