我有这样一张桌子:
Item
{
int ItemID
int ParentID
string Name
}
Item实际上是较大的表Object的子集:
Object
{
int ObjectID
string Color
}
所以ItemID是一个FK到ObjectID.在Item中,ParentID可以引用另一个Item或父Object.
我想做的是能够从Item关系中的一个叶子一直迭代到它的父节点,直到我最终可以确定给定的Item叶子从哪个ObjectID下降.
我想在SQL中这样做.我正在使用SQL Server 2008.
这就是我在想的.我可以通过Item ParentID迭代,直到我不能再将ParentID与另一个Item连接.这个ParentID是我想要返回的ObjectID.
我一直试图使用内部连接来实现这一点,但没有运气.我正在使用C#所以如果这可以在linq中完成,我不怀疑它可以没有非常低效,那也没关系.
回答我去了:
WITH ObjectH (ParentID, ItemID, Level) AS
(
-- Base case
SELECT
ParentID,
ItemID,
1 as Level
FROM Item
WHERE ItemID = @param
UNION ALL
-- Recursive step
SELECT
i.ParentID,
i.ItemID,
oh.Level + 1 AS Level
FROM Item i
INNER JOIN ObjectH oh ON
c.ItemID = oh.ParentID
)
SELECT TOP 1 ParentID
FROM ObjectH
ORDER BY Level DESC
这有效.
最佳答案 我尝试使用递归SQL Server CTE执行此操作.
从逻辑上讲,这就是CTE的工作原理,但是我从来没有将它用于与您的模式完全相同的模式.
通常SQL中的树结构不具有附加的父“对象”表. (好像你正在模仿你的对象在数据库中完全按1:1设计?如果我是你,我会重新看到那个模式)
尝试一下,让我知道它是否有效.
编辑:稍微更改了基本查询条件
EDIT2:更改了查询以使其特定于一个项目
WITH ObjectHierarchy (ItemID, Name, ParentID, Level) AS
(
SELECT
ItemID,
Name,
ParentID,
1 as Level
FROM Item it, Object ob
WHERE it.ParentID = ob.ObjectID
AND ob.ItemID = @itemIdToBeSearched
UNION ALL
SELECT
i.ItemID,
i.Name,
i.ParentID,
oh.Level + 1 AS Level
FROM Item i
INNER JOIN ObjectHierarchy oh ON
i.ParentID = oh.ItemID
AND oh.ItemID = @itemIdToBeSearched
)
SELECT parentID
FROM ObjectHierarchy
WHERE LEVEL = 1