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

Откуда: Россия. Санкт-Петербург
Сообщений: 3194
Если таблица со следующей структурой:
UserIdParentUserID
1null
21
32
42
53
65


На входе есть дочерний UserId и UserId родительского элемента (не прямого родителя и не root, а какого-либо промежуточного).
Необходимо получить первого чилда относительно заданного родителя. То есть, если дочерний UserId = 6, а родительский UserId = 3, то запрос должен вернуть 5.

Сделал следующий запрос, но он не особого помогает решить задачу. Помогите, пожалуйста.

WITH RCTE AS
(
    SELECT  UserID, ParentUserID, Name, 1 AS Lvl FROM users  
	where ParentUserID not in (select UserID from users )

    UNION ALL

    SELECT rh.UserID, rh.ParentUserID, rh.Name, Lvl+1 AS Lvl 
    FROM users  rh
    INNER JOIN RCTE rc ON rh.ParentUserID = rc.UserID
)
SELECT r.UserID, r.ParentUserID, Lvl, Name
FROM RCTE r
25 ноя 16, 15:25    [19934862]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
[quot Vsevolod V]Если таблица со следующей структурой:
UserIdParentUserID
1null
21
32
42
53
65


На входе есть дочерний UserId и UserId родительского элемента (не прямого родителя и не root, а какого-либо промежуточного).
Необходимо получить первого чилда относительно заданного родителя. То есть, если дочерний UserId = 6, а родительский UserId = 3, то запрос должен вернуть 5.
[quot]
По текущей формулировке задачи
SELECT [UserId] FROM users WHERE ParentUserID = @parentid

и никаких извращений.
Поэтому озвучивайте всю задачу целиком.
25 ноя 16, 15:38    [19934951]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
cte,
Guest
declare @t table (UserId int, ParentUserID int)

insert into @t values
(1, null), 
(2, 1), 
(3, 2), 
(4, 2), 
(5, 3), 
(6, 5) 

select * from @t

declare @UserId int=6, @ParentUserID int=3

;with cte as (
select ParentUserID as ID, 1 as lvl from @t where UserId=@UserId and ParentUserID<>@ParentUserID

union all

select t.ParentUserID, cte.lvl+1
from @t t inner join cte on t.UserId=cte.ID 
where t.ParentUserID<>@ParentUserID
)

select top 1 ID from cte order by lvl desc
25 ноя 16, 15:38    [19934953]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3194
cte,,

Спасибо большое. То что надо!
И скажите еще, пожалуйста, как использовать этот запрос максимально эффективно?
У меня есть набор данных, с которым хотелось бы заджойнить результаты этого запроса. В идеале, конечно, чтобы это был сохраненный вью. Но поскольку запрос сильно завязан на параметры, то не ясно, какие есть выходы?
27 ноя 16, 14:28    [19939683]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3194
up
28 ноя 16, 12:24    [19942323]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
cte,
Guest
Vsevolod V
cte,,

Спасибо большое. То что надо!
И скажите еще, пожалуйста, как использовать этот запрос максимально эффективно?
У меня есть набор данных, с которым хотелось бы заджойнить результаты этого запроса. В идеале, конечно, чтобы это был сохраненный вью. Но поскольку запрос сильно завязан на параметры, то не ясно, какие есть выходы?

инлайн функция, которая будет принимать эти 2-а параметра

пс
и в запросе нужно ещё добавить обработку ситуации, когда заданный @ParentUserID не является предком заданного @UserId
28 ноя 16, 13:07    [19942534]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3194
cte,,

да, я пробовал так. Но функция ругается, что селекты запрещены сразу в самом начале кода - подчеркивает текст "with cte as"
28 ноя 16, 17:12    [19943784]     Ответить | Цитировать Сообщить модератору
 Re: Запрос по древовидной структуре данных  [new]
o-o
Guest
Vsevolod V
cte,,

да, я пробовал так. Но функция ругается, что селекты запрещены сразу в самом начале кода - подчеркивает текст "with cte as"

create table dbo.t(UserId int, ParentUserID int);

insert into dbo.t values
(1, null), 
(2, 1), 
(3, 2), 
(4, 2), 
(5, 3), 
(6, 5); 
GO

create function dbo.func(@UserId int, @ParentUserID int)
returns table

return
with cte as (
select ParentUserID as ID, 1 as lvl from dbo.t where UserId=@UserId and ParentUserID<>@ParentUserID

union all

select t.ParentUserID, cte.lvl+1
from dbo.t t inner join cte on t.UserId=cte.ID 
where t.ParentUserID<>@ParentUserID
)

 select top 1 ID from cte order by lvl desc;
go

declare @UserId int=6, @ParentUserID int=3;
select *
from dbo.func(@UserId, @ParentUserID);
28 ноя 16, 17:55    [19943983]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить