Как получить все строки восходящих и потомков в SQL с рекурсией - PullRequest
1 голос
/ 23 декабря 2011

у меня есть следующие данные таблицы в категории имени таблицы сервера ms sql

table data and schema

и проблема в том, что я хочу получить данные о родителях, родителях, братьях и сестрах, дочерних и дочерних дочерних элементах и ​​себе.

Надеюсь, вы поняли мою точку зрения, если мне понадобятся дополнительные разъяснения по моему требованию, я могу отредактировать свой вопрос, просто оставив комментарий ниже.

Что касается моей попытки, я искал stackoverflow и нашел много примеров получения полных иерархических данных с использованием parent, но не нашел ничего, что касалось передачи потомка и получения parent, sub child и self.

Я также открыт для решения, которое предоставляет мне решение с использованием linq, потому что тогда я могу получить полные данные в категории и использовать их на странице .cs.

Редактировать: если я передам 7, который равен heritage CategoryId, то запрос должен вернуть следующие строки

desired result in case category id 7 pass

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Ответ заключается в использовании рекурсивного «Общего выражения таблицы», или CTE. Это позволяет вам построить структуру вашей иерархии. Ниже приведен пример, измененный в соответствии с вашей структурой на основе этой страницы: http://msdn.microsoft.com/en-us/library/ms186243.aspx

WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level) 
AS 
( 
-- Anchor member definition 
SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
0 AS Level 
FROM Category AS c 
WHERE c.ParentCategoryID=0 
UNION ALL 
-- Recursive member definition 
SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
Level + 1 
FROM Category AS c 

INNER JOIN CategoryStructured AS c_parent 
ON c.ParentCategoryID = c_parent.CategoryID 
) 
-- Statement that executes the CTE 
SELECT distinct cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level 
FROM 
CategoryStructured cs, 


(SELECT level,ParentCategoryID,CategoryID from CategoryStructured WHERE (categoryID = 4) OR (level = 1 AND parentCategoryID = 4)) as thisCategory 


WHERE cs.level BETWEEN thisCategory.level - 1 AND thisCategory.level+1 
AND ((thisCategory.level != 0 AND cs.ParentCategoryID = thisCategory.ParentCategoryID) 
OR cs.categoryID = thisCategory.ParentCategoryID 
OR cs.ParentCategoryID = thisCategory.CategoryID 
OR cs.CategoryID = thisCategory.CategoryID)

Обновлено, чтобы отразить ваш обновленный вопрос.

edit Я знаю, что вы смогли заставить вышеперечисленное в основном работать для вас с добавленными отличиями, но я подумал о лучшем способе справиться с этим после того, как я покинул чат:

WITH CategoryStructured (ParentCategoryID, CategoryID, Description, Status, Level)
AS
(
-- Anchor member definition
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
        0 AS Level
    FROM Categories AS c
    WHERE 
     (c.ParentCategoryID IS NULL AND c.categoryID = 7) -- when 7 is a top level category, then it is the root level
     OR (c.categoryID = (SELECT c2.parentCategoryID FROM Categories c2 WHERE c2.categoryID = 7)) -- when 7 is some non-top level category, then 7's parent is the root
    UNION ALL
-- Recursive member definition
    SELECT c.ParentCategoryID, c.CategoryID, c.Description, c.Status, 
        Level + 1
    FROM Categories AS c

    INNER JOIN CategoryStructured AS c_parent
        ON c.ParentCategoryID = c_parent.CategoryID
)
-- Statement that executes the CTE
SELECT cs.ParentCategoryID, cs.CategoryID, cs.Description, cs.Status, cs.Level
FROM 
  CategoryStructured cs
WHERE cs.level < 3
ORDER BY cs.level
0 голосов
/ 23 декабря 2011

Как я это делаю, создаю функцию и заставляю ее вызывать себя для каждого уровня программы, если вы пытаетесь вывести данные ud, записывать каждый уровень или собираете какой-то массив в публичной области видимости или статическая переменная / синглтон.

Это не красиво, но рекурсия редко когда-либо бывает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...