Sql server 2008 SQLServer2008中的递归同表查询
SQL Server 2008数据库中有下表:Sql server 2008 SQLServer2008中的递归同表查询,sql-server-2008,recursion,Sql Server 2008,Recursion,SQL Server 2008数据库中有下表: Id Name ParentFolder -- ---- ------------ 1 Europe NULL 2 Asia NULL 3 Germany 1 4 UK 1 5 China 2 6 India 2 7 Scotland 4 ParentFolder是同一表中的FK to Id。我想创建一个视图,其结果如下: I
Id Name ParentFolder
-- ---- ------------
1 Europe NULL
2 Asia NULL
3 Germany 1
4 UK 1
5 China 2
6 India 2
7 Scotland 4
ParentFolder是同一表中的FK to Id。我想创建一个视图,其结果如下:
Id Name FullName
-- ---- --------
1 Europe Europe
2 Asia Asia
3 Germany Europe/Germany
4 UK Europe/UK
5 China Asia/China
6 India Asia/India
7 Scotland Europe/UK/Scotland
如您所见,我需要通过递归使用ParentFolder关系任意次数构建FullName值,直到找到NULL
编辑。表中的每一行“知道”另一行是其父行,但不知道其在层次结构中的绝对位置。因此,在谱系系统中,每行存储其在层次结构树中的绝对位置是不合适的
我知道SQLServer2008的分层特性,但据我所知,它只适用于固定数量的递归级别。然而,在我的例子中,你永远不知道你会找到多少层,它们可能会随着行的变化而变化
我在这里也看到了类似的问题。然而,我认为没有人问过为表中的每一行构建“路径”。如果我错过了,很抱歉
非常感谢。我不确定这是否适用于您的情况,但在本例中,使用了一个额外的列,称为沿袭
我成功地使用了此方法。听起来您应该签出Sql Server。 CLR集成意味着您现在可以使用任何.NET Framework语言编写存储过程、触发器、用户定义类型、用户定义函数(标量和表值)和用户定义聚合函数,包括Microsoft Visual Basic.NET和Microsoft Visual C。\
DECLARE @tbl TABLE (
Id INT
,[Name] VARCHAR(20)
,ParentId INT
)
INSERT INTO @tbl( Id, Name, ParentId )
VALUES
(1, 'Europe', NULL)
,(2, 'Asia', NULL)
,(3, 'Germany', 1)
,(4, 'UK', 1)
,(5, 'China', 2)
,(6, 'India', 2)
,(7, 'Scotland', 4)
,(8, 'Edinburgh', 7)
,(9, 'Leith', 8)
;
WITH abcd
AS (
-- anchor
SELECT id, [Name], ParentID,
CAST(([Name]) AS VARCHAR(1000)) AS "Path"
FROM @tbl
WHERE ParentId IS NULL
UNION ALL
--recursive member
SELECT t.id, t.[Name], t.ParentID,
CAST((a.path + '/' + t.Name) AS VARCHAR(1000)) AS "Path"
FROM @tbl AS t
JOIN abcd AS a
ON t.ParentId = a.id
)
SELECT * FROM abcd
我尝试了上面的解决方案,但发现这只适用于我的两个级别。(也许我没有理解或错过一些东西。) 为了获得m解决方案的完全限定路径,我已成功使用此自定义函数:
CREATE FUNCTION GetFQN(@recid int)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @path AS VARCHAR(1000)
DECLARE @parent_recid AS INT
SET @path = (SELECT BranchName FROM Branches WHERE Recid = @recid)
SET @parent_recid = (SELECT recid_parent FROM Branches WHERE Recid = @recid)
WHILE @parent_recid != -1
BEGIN
SET @path = (SELECT BranchName FROM Branches WHERE recid = @parent_recid) + '/' + @path
SET @parent_recid = (SELECT recid_parent FROM Branches WHERE recid = @parent_recid)
END
RETURN (@Path)
END
谢谢你,约翰。我不确定这是否有效,因为沿袭列意味着表中的每一行都必须“知道”其在层次结构中的绝对位置。我在我的原始帖子中没有提到这一点(现在编辑以澄清),但我宁愿避免使用这种绝对定位系统。:-)谢谢你,查德。因此,基本上,您是说我需要在C#(或VB.NET)中创建一个表值函数,并使用它来计算视图中的全名列,对吗?@CesarO:是的。我认为用c#作为CLR SP或函数编写解决方案将比我为此而设计的TSQL的gooble更容易。我还认为这将比TSQL更有效(因为与游标关联的锁/闩锁)。幸运的是,你真的不需要编写CLR函数,看看下面Damir Sudarevic的答案。“公共表表达式”解决了大多数分层数据问题。