Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Рекурсивный запрос  [new]
ramons
Member

Откуда:
Сообщений: 18
Добрый день.
Такой вопрос.
[url=]http://social.msdn.microsoft.com/Forums/en/transactsql/thread/6dfd0140-d018-481f-9363-c0ab49d9517f[/url]
Здесь приведен примера рекурсивного запроса.

CREATE TABLE EmployeeTree(
	EmployeeId int,
        EmployeeName nvarchar(100),
        EmployeeType nvarchar(40),
	EmployeeParentId int 
)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (1, 'Mickey Mouse', 'CEO', NULL)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (2, 'Minnie Mouse', 'President', 1)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (3, 'Donald Duck', 'Division Head', 2)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (4, 'Daffy Duck', 'Division Head', 2)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (5, 'Scrooge McDuck', 'Department Head', 3)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (6, 'Huey McDuck', 'Team Lead', 5)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (7, 'Dewey McDuck', 'Team Lead', 5)

INSERT INTO EmployeeTree (EmployeeId, EmployeeName, EmployeeType, EmployeeParentId)
VALUES (8, 'Louie McDuck', 'Team Member', 7)

declare @Type varchar(40) = 'Division Head'
declare @Name varchar(100) = 'Louie McDuck'


-- Anchor definition
;with cte as (
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID, 
		Case 
			when E.EmployeeType = @Type then E.EmployeeName 
		end as [Division Head], 
		0 as Level, 
		P.EmployeeName as HeadName, 
		P.EmployeeType as HeadType 
	from EmployeeTree E 
		LEFT join EmployeeTree P on E.EmployeeParentId = P.EmployeeId 
	where P.EmployeeId IS NULL
	
union all 

-- recursive part
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID, 
		Case 
			when P.EmployeeType = @Type then P.EmployeeName 
			else [Division Head] 
		end as [Division Head] ,
		Level + 1 as Level, 
		P.EmployeeName as HeadName, 
		P.EmployeeType as HeadType
	from EmployeeTree E 
		inner join cte P on E.EmployeeParentId  = P.EmployeeId
)

select * from cte  where EmployeeName = @Name


Данный запрос показывает указанный парент для указанного узла дерева.
Помогите переписать данный запрос так, что бы он возвращал путь до верхнего элемента дерева.
15 дек 11, 19:48    [11774509]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
ramons
что бы он возвращал путь до верхнего элемента дерева.
;with cte as (
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID, 
		Case 
			when E.EmployeeType = @Type then E.EmployeeName 
		end as [Division Head], 
		0 as Level, 
		P.EmployeeName as HeadName, 
		P.EmployeeType as HeadType,
		cast(E.EmployeeName as nvarchar(max)) as path
	from EmployeeTree E 
		LEFT join EmployeeTree P on E.EmployeeParentId = P.EmployeeId 
	where P.EmployeeId IS NULL
	
union all 

-- recursive part
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID, 
		Case 
			when P.EmployeeType = @Type then P.EmployeeName 
			else [Division Head] 
		end as [Division Head] ,
		Level + 1 as Level, 
		P.EmployeeName as HeadName, 
		P.EmployeeType as HeadType,
		E.EmployeeName + ' => ' + P.path
	from EmployeeTree E 
		inner join cte P on E.EmployeeParentId  = P.EmployeeId
)

select * from cte  where EmployeeName = @Name
15 дек 11, 19:58    [11774564]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
ramons
Member

Откуда:
Сообщений: 18
Извиняюсь за не точную задачу.
я хотел вывести путь в табличном виде.
то есть что бы у меня была результирущая таблица содержащая путь от нежнего чилда к верхнему парунту
16 дек 11, 00:18    [11775378]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
Покажите как должен выглядеть результат
16 дек 11, 11:22    [11776404]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
ramons
Member

Откуда:
Сообщений: 18

8 Louie McDuck Team Member 7
7 Dewey McDuck Team Lead 5
5 Scrooge McDuck Department Head 3
3 Donald Duck Division Head 2
2 Minnie Mouse President 1
1 Mickey Mouse CEO NULL

16 дек 11, 11:49    [11776587]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
;with cte as (
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID
	from EmployeeTree E 
		LEFT join EmployeeTree P on E.EmployeeParentId = P.EmployeeId 
	where E.EmployeeName = @Name
	
union all 

-- recursive part
	select E.EmployeeID, E.EmployeeName, E.EmployeeType, E.EmployeeParentId as HeadID
	from EmployeeTree E 
		inner join cte P on P.HeadID  = E.EmployeeId
)

select * from cte
16 дек 11, 11:59    [11776655]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
ну и это
LEFT join EmployeeTree P on E.EmployeeParentId = P.EmployeeId
можно выкинуть раз колонок нужно меньше
16 дек 11, 12:02    [11776687]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
ramons
Member

Откуда:
Сообщений: 18
Спасибо большое.

То есть получается что первая выборка в запросе -- начальная точка отсчета.
16 дек 11, 12:42    [11776923]     Ответить | Цитировать Сообщить модератору
 Re: Рекурсивный запрос  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
да
16 дек 11, 12:43    [11776926]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить