I am working on a website which have pages arranged in one table with Parent Child Relation. Page depth can go to any level and i want to generate BreadCrumb for the website based on the database. Sample Data and data fields as shown in the Image below.
Basic Table Structure is like TableName Web_Pages
Table Columns ( PageID int, PageName Varchar, PageInternalLinkURL Varchar,PageInheritance int)
Example of Sample Data in the table
Example of BreadCrumb on Page
I want the Bread crumb for the site navigation to look similar to what is shown in the sample image below.
I tried for weeks but was not able to get it right.
I want to use it with out site map, rather i would like to create it grammatically and link the PageName field with the correct Page URL.
I want to do it so that when ever a page is added to CMS Bread crumb is created dynamically which can work with any page depth.
I worked with CTE query which is not working properly. I would appreciate if someone resolve this issue or can point to a complete working example which is similar to mine.
Testing CTE not working
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
It looks like your CTE is wrong - you are almost there but the Recursive Member Definition bit looks wrong.
Try:
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
In your original attempt, your alias for pg_Pages needs to be tt (and you need to prefix PageInheritance with tt too).
Otherwise, it looks fine.
EDIT
For your additional question, you can just add the additional columns:
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
FURTHER EDIT:
Okay, to do what you want, you can turn the query around; provided you know the page 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
What we do here is start off at the page you are on, then work backwards through the table looking for all parents. In this instance, the record with the highest level is the ultimate parent, so we order by level in descending order to reflect this.