Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 SQLServer2008中的递归同表查询_Sql Server 2008_Recursion - Fatal编程技术网

Sql server 2008 SQLServer2008中的递归同表查询

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

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。我想创建一个视图,其结果如下:

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的答案。“公共表表达式”解决了大多数分层数据问题。