0

私は、親子関係のある1つのテーブルにページが配置されているWebサイトに取り組んでいます。ページの深さはどのレベルにもなる可能性があり、データベースに基づいてWebサイトのBreadCrumbを生成したいと思います。下の画像に示すサンプルデータとデータフィールド。

基本的なテーブル構造はTableNameWeb_Pagesに似ています

テーブル列 (PageID int、PageName Varchar、PageInternalLinkURL Varchar、PageInheritance int)

表のサンプルデータの例 テーブルデータの例

ページ上のブレッドクラムの例 ページ上のブレッドクラムの例

サイトナビゲーション用のパンくずを、下のサンプル画像に示されているもののように見せたいです。

私は何週間も試しましたが、正しく理解できませんでした。

サイトマップなしで使用したいのですが、文法的に作成し、PageNameフィールドを正しいページURLにリンクしたいと思います。

ページがCMSに追加されるたびに、任意のページ深度で機能するパンくずが動的に作成されるようにしたいと思います。

正しく機能していないCTEクエリを使用しました。誰かがこの問題を解決するか、私のような完全な実例を指摘していただければ幸いです。

CTEのテストが機能しない

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId, tt.PageInheritance, LEVEL + 1
    FROM pg_Pages AS PageId
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
4

2 に答える 2

2

あなたの CTE が間違っているようです - あなたはほとんどそこにいますが、再帰メンバー定義ビットが間違っているようです.

試す:

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId, tt.PageInheritance, Level + 1
    FROM pg_Pages AS tt
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
--SELECT * FROM RecursiveTable WHERE Level = 0

最初の試みでは、pg_Pages のエイリアスを tt にする必要があります (また、PageInheritance の前に tt を付ける必要があります)。

それ以外の場合は、問題ないように見えます。

編集

追加の質問については、追加の列を追加するだけです。

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
    FROM pg_Pages AS tt
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable
--SELECT * FROM RecursiveTable WHERE Level = 0

さらに編集:

さて、やりたいことをするために、クエリを逆にすることができます。ページIDがわかっている場合:

DECLARE @PageId int
SET @PageId = 39;
WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
AS(
   --Anchor
    SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
    FROM TestPage AS tt
    WHERE PageId = @PageId
    UNION ALL
   --Recursion
    SELECT tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
    FROM TestPage AS tt
    INNER JOIN RecursiveTable rt ON rt.PageInheritance = tt.PageId
)
SELECT * FROM RecursiveTable ORDER BY Level DESC

ここで行うことは、現在表示しているページから始めて、すべての親を探してテーブルを逆方向​​に作業することです。この例では、最高レベルのレコードが最終的な親であるため、これを反映するためにレベルの降順で並べ替えます。

于 2012-04-18T08:22:54.907 に答える
0

pageId 39 のブレッドクラムを取得したいと仮定すると、次のようなことを試すことができます。

declare @pageId int

set @pageId=39;
WITH RecursiveTable (PageId,PageName, PageInheritance,PageInternalLinkURL, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,tt.PageName,  tt.PageInheritance,tt.PageInternalLinkURL,  0 AS Level
    FROM pg_pages AS tt
    WHERE PageID = @pageId
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId,tt.PageName,  tt.PageInheritance,tt.PageInternalLinkURL, Level + 1
    FROM pg_pages AS tt
        INNER JOIN RecursiveTable rt ON
        rt.PageInheritance = tt.PageId
)
SELECT * 
FROM RecursiveTable
于 2012-04-18T09:40:09.613 に答える