Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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 递归CTE查询生成产品或页面层次结构_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql 递归CTE查询生成产品或页面层次结构

Sql 递归CTE查询生成产品或页面层次结构,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我想为asp.net路由生成以下路径,我也可以将其用于面包屑导航 Page_ID Page_Name Page_Title Page_Handler Parent_Page_ID Language_ID Region_ID 1 Home Home index.aspx 0

我想为asp.net路由生成以下路径,我也可以将其用于面包屑导航

Page_ID     Page_Name               Page_Title              Page_Handler        Parent_Page_ID  Language_ID     Region_ID
1           Home                    Home                    index.aspx              0               1               uae
2           Personal                Personal                index.aspx              0               1               uae
3           Accounts & Deposits     Accounts & Deposits     index.aspx              2               1               uae
4           Current Account         Current Account         current-account.aspx    3               1               uae
5           Current Gold Accounts   gold Account            gold-account.aspx       3               1               uae
6           Easy Saver              Easy Saver Account      saver-account.aspx      3               1               uae
7           Fixed Deposits          Fixed Account           fixed-account.aspx      3               1               uae
8           Loans                   Loans                   index.aspx              2               1               uae
9           Personal Loans          Personal Loans          index.aspx              8               1               uae
10          car Loans               car Loans               car-loan.aspx           8               1               uae
我已经修改了一个CTE脚本来处理我的表的类似结构。但这个CTE的问题是它给了我兄弟姐妹/孩子/父母的身份。。。而我需要的路径是父/子/兄弟

范例

示例代码-由于sqlfiddle上的限制,我使用了短数据

www.abc.com/home
www.abc.com/personal
www.abc.com/personal/acounts-deposits/
www.abc.com/personal/acounts-deposits/current-account
www.abc.com/personal/acounts-deposits/current-gold-account
www.abc.com/personal/acounts-deposits/easy-saver
......
......
www.abc.com/personal/loans/
www.abc.com/personal/loans/personal-loans
www.abc.com/personal/loans/car-loans

如果我理解正确,这将是我解决这个问题的方法。这可能不是一个完整的答案,但它会让你接近某个地方

CREATE TABLE PageMenu
    ([PageId] int, [PageName] varchar(5), [PageInheritance] int)
;

INSERT INTO PageMenu
    ([PageId], [PageName], [PageInheritance])
VALUES
    (1, 'home', 0),
    (2, 'p1', 0),
    (3, 'c1', 2),
    (4, 'c2', 2),
    (5, 's3', 4),
    (6, 'S3a', 5)
;
WITH CategoryCTE AS
(   SELECT  PageId, 
            PageName, 
            PageInheritance, 
            RecursionLevel = 1, 
            ParentRoot = CAST('None' AS VARCHAR(MAX)),
            LastParentCatID = PageInheritance
    FROM    PageMenu
    UNION ALL
    SELECT  cte.PageId, 
            cte.PageName,
            cte.PageInheritance,
            cte.RecursionLevel + 1,
            ParentRoot = CASE WHEN cte.RecursionLevel = 1 THEN '' ELSE cte.ParentRoot + '/' END + c.PageName,
            LastParentCatID = c.PageInheritance
    FROM    CategoryCTE cte
            INNER JOIN PageMenu c
                ON c.PageId = cte.LastParentCatID
), MaxRecursion AS
(   SELECT  PageId, 
            PageName, 
            PageInheritance, 
            ParentRoot, 
            RowNum = ROW_NUMBER() OVER(PARTITION BY PageId ORDER BY RecursionLevel DESC)
    FROM    CategoryCTE
)
SELECT  PageId, PageName, PageInheritance, ParentRoot
FROM    MaxRecursion
WHERE   RowNum = 1 ORDER BY PageId DESC;
我认为M.Ali的(在评论中做了更正)比你的方法更合适。无论如何,如果您只想更正查询,那么将ParentRoot计算从递归查询更改为:

╔═════════════════════╗
║        Paths        ║
╠═════════════════════╣
║ www.abc.com/1       ║
║ www.abc.com/2       ║
║ www.abc.com/2/4     ║
║ www.abc.com/2/3     ║
║ www.abc.com/2/4/5   ║
║ www.abc.com/2/4/5/6 ║
╚═════════════════════╝

这个给定测试数据的预期输出是什么???我将更改WHERE子句,删除左函数(不可搜索),并按WHERE PAGEHERITY=0进行更改。此外,编辑后,您还可以轻松地从CTE查询的结果集中删除“0/”,从而避免复杂的字符串操作。如下所示:在锚查询中:CASE WHEN cast(t.pageheritance为nvarchar(max))N'0'然后cast(t.pageheritance为nvarchar(max))+'/'+cast(t.PageId为nvarchar(max))ELSE cast(t.PageId为nvarchar(max))在递归查询中结束为[Path]:CASE WHEN cast(t.pageheritance为nvarchar(max))N'0'然后cast.pageheritance为nvarchar(max))+'/'+c.[Path]否则c.[Path]以[Path]结尾请投票支持我的评论(如果有用的话):)非常感谢指针它确实使它更简单、更高效。:)@阿里先生,如果您能将其更改为在结果中显示
PageName
,而不是
PageID
,我将不胜感激。我试图改变,但我搞砸了一点,因为它在接近尾声时得到了错误的结果
http://sqlfiddle.com/#!3/0d086/22
@KnowledgeSeeker在主播查询中用t.PageName替换cast(t.PageId为nvarchar(max))(两次)。@Jame,谢谢,它看起来不错,我只是想通过添加过滤器
来进一步增强这个CTE,其中PageID=x
,这样我就可以获得相应的PageID的路径only@KnowledgeSeeker可以将该筛选条件添加到已存在的筛选中。如下所示:其中RowNum=1,PageId=XThanks。。我会给你的答案打上正确的标记,因为它与我的问题+1更相关
╔═════════════════════╗
║        Paths        ║
╠═════════════════════╣
║ www.abc.com/1       ║
║ www.abc.com/2       ║
║ www.abc.com/2/4     ║
║ www.abc.com/2/3     ║
║ www.abc.com/2/4/5   ║
║ www.abc.com/2/4/5/6 ║
╚═════════════════════╝
ParentRoot = CASE WHEN cte.ParentRoot <> 'None' THEN c.PageName + '/' + cte.ParentRoot ELSE c.PageName END,
    WITH CategoryCTE AS
(   SELECT  PageId, 
            PageName, 
            PageInheritance, 
            RecursionLevel = 1, 
            ParentRoot = CAST('None' AS VARCHAR(MAX)),
            LastParentCatID = PageInheritance
    FROM    PageMenu
    UNION ALL
    SELECT  cte.PageId, 
            cte.PageName,
            cte.PageInheritance,
            cte.RecursionLevel + 1,
            ParentRoot = CASE WHEN cte.ParentRoot <> 'None' THEN c.PageName + '/' + cte.ParentRoot ELSE c.PageName END,
            LastParentCatID = c.PageInheritance
    FROM    CategoryCTE cte
            INNER JOIN PageMenu c
                ON c.PageId = cte.LastParentCatID
), MaxRecursion AS
(   SELECT  PageId, 
            PageName, 
            PageInheritance, 
            ParentRoot, 
            RowNum = ROW_NUMBER() OVER(PARTITION BY PageId ORDER BY RecursionLevel DESC)
    FROM    CategoryCTE
)
SELECT  PageId, PageName, PageInheritance, ParentRoot
FROM    MaxRecursion
WHERE   RowNum = 1 
ORDER BY PageId DESC;
;with cte 
as (
    select
    t.PageInheritance, 1 as Level, 
    cast(t.Pagename as nvarchar(max)) AS [Path]
    from PageMenu as t

    union all

    select
    t.PageInheritance, Level + 1 as Level,
    cast(t.PageName as nvarchar(max)) + '/' + c.[Path] as [Path] 
    from PageMenu as t  
    inner join cte as c on c.PageInheritance = t.PageId
)
select N'www.abc.com/' + [Path] AS [Paths]
from cte 
WHERE PageInheritance = 0
order by [Level] ASC