Как я РЕГУЛИРУЮТ РЕКУРСИЮ в SQL?
У меня есть таблица:
Series
========
ID
SeriesName
ParentSeriesID
Ряд может быть "корневым" рядом, (ParentSeriesID
равен 0 или null) или может иметь родительский элемент. Серия также может быть несколько уровней вниз, то есть ее родитель имеет родителя, у которого есть родитель и т.д.
Как я могу запросить таблицу, чтобы получить серию по ее идентификатору и всем сериям потомков?
До сих пор я пробовал:
SELECT child.*
FROM Series parent JOIN Series child ON child.ParentSeriesID = parent.ID
WHERE parent.ID = @ParentID
Но это возвращает только первый уровень детей, я хочу родительский node и все "нисходящие" узлы. Я не уверен, как продвигаться отсюда.
Ответы
Ответ 1
Если вы используете SQL Server 2005+, вы можете использовать выражения common-table
With Family As
(
Select s.ID, s.ParentSeriesId, 0 as Depth
From Series s
Where ID = @ParentID
Union All
Select s2.ID, s2.ParentSeriesId, Depth + 1
From Series s2
Join Family
On Family.ID = s2.ParentSeriesId
)
Select *
From Family
Подробнее:
Рекурсивные запросы с использованием общих выражений таблицы
Ответ 2
Я только усиливаю работу Томаса. Если вам нужно получить глубину иерархии и получить родительский код здесь, это код.
Это было почти то же самое с работой Томаса.
With Family As
(
Select s.ID, s.ParentSeriesId, 0 as Depth
From Series s
Where ID = @ParentID <--- this was removed if you intend to get all hierarchy of the record. You can retain this if you want
Union All
Select s2.ID, s2.ParentSeriesId < --- change to **Family.ParentID**, Depth + 1
From Series s2
Join Family
On Family.ID = s2.ParentSeriesId
)
Select *
From Family
Это все. Я знаю это слишком поздно, но я надеюсь, что кто-нибудь, кто столкнутся с этим, может им помочь. Спасибо Томасу за оригинальный код.:)
Ответ 3
Использовать функцию CTE
, доступную в slq-сервере 2005 года для повторного запроса
USE AdventureWorks
GO
WITH Emp_CTE AS (
SELECT EmployeeID, ContactID, LoginID, ManagerID, Title, BirthDate
FROM HumanResources.Employee
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.ContactID, e.LoginID, e.ManagerID, e.Title, e.BirthDate
FROM HumanResources.Employee e
INNER JOIN Emp_CTE ecte ON ecte.EmployeeID = e.ManagerID
)
SELECT *
FROM Emp_CTE
GO
Вы можете посмотреть пример здесь:
SQL SERVER - простой пример рекурсивного CTE