Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
ErikI Member Откуда: Сообщений: 162 |
Внутри SQL запроса используется sub query для составления пути SYS_CONNECT_BY_PATH(Oracle) Для MS SQL сервера надо написать аналогичную конструкцию. Хотел использовать WITH, но он же не может выступать как sub query? Или опять попробовать использовать FOR XML PATH? |
9 авг 16, 16:17 [19520881] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
cte можно засунуть в табличную функцию и потом ее apply-ить --- совет хотите? не пытайтесь дословно перевести оракловый код. лучше заново ставить себе задачу: вот то на входе, вот это хочу на выходе. и решать эту задачу на T-SQL. а то получите говнокод с такой же говнопроизводительностью |
9 авг 16, 16:41 [19521002] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47045 |
Надо написать один WITH на весь запрос, но несколько определений CTE, раздёлённых запятыми. Каждое CTE может обращаться к любому вышестоящему в списке неограниченное количество раз. После последнего CTE, разумеется, надо написать основной запрос с возможнстью использования любых определённых в WITH CTE. Но надо, всё-таки, подумать, может не надо пытаться точно копировать конструкцию в Oracle? |
||
9 авг 16, 16:51 [19521040] Ответить | Цитировать Сообщить модератору |
ErikI Member Откуда: Сообщений: 162 |
Тогда вопрос по hierarchyid. Как с помощью её получить путь от корня до последнего потомка в виде агрегированой строки? Это возможно? |
9 авг 16, 17:00 [19521086] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
да он же про рекурсию. типа каждому манагеру найти его подчиненных и этот подсчет подчиненных зафигачить в cte. не поможет куча cte через зпт, ибо манагер меняется, т.е. он якорь передает в cte, ну т.е. функцию ему надо |
||||
9 авг 16, 17:06 [19521130] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8299 |
ErikI, hierarchyid и есть агрегированная строка в символьном написании. \1\2\3 Если правильно помню, там есть ограничение на имя узла - то ли 20, то ли 32 символа. |
9 авг 16, 17:25 [19521244] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8299 |
Если вопрос о том, как записи собрать в строку, то ответ есть в FAQ. |
9 авг 16, 17:26 [19521251] Ответить | Цитировать Сообщить модератору |
ErikI Member Откуда: Сообщений: 162 |
Надо не просто забросить а сделать это в рекурсии. |
9 авг 16, 17:28 [19521263] Ответить | Цитировать Сообщить модератору |
Владислав Колосов Member Откуда: Сообщений: 8299 |
hierarchyid работает без рекурсии и эффективнее СТЕ, если требуется за один проход найти ветки нескольких корней. Но надо понимать, что один раз потребуется иерархически пронумеровать каждую запись и эту иерархию поддерживать при добавлении-удалении. |
9 авг 16, 17:41 [19521336] Ответить | Цитировать Сообщить модератору |
ErikI Member Откуда: Сообщений: 162 |
o-o, Разве сте не поддерживает смену якоря? Мне для каждой строки нужен корректный путь до корня. |
9 авг 16, 17:43 [19521348] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
держите, разбирайтесь убегаю create table [dbo].[users]( [userid] [int] , [username] [varchar](50) , [managerid] [int] , ) insert into dbo.users ([userid], [username], [managerid]) values (1,'aaa',null), (2,'bbb',1), (3,'ccc',2), (4,'ddd',1), (5,'eee',3), (6,'fff',5), (7,'ggg',5), (8,'hhh',4); go create function dbo.udf_erik(@id int) returns table as return with usercte as (select userid, username, managerid, 0 as emplevel from [users] where managerid = @id union all select usr.userid, usr.username, usr.managerid, mgr.[emplevel] + 1 from [users] as usr inner join usercte as mgr on usr.managerid = mgr.userid where usr.managerid is not null) select * from usercte as u; select * from dbo.udf_erik(3); |
9 авг 16, 17:56 [19521401] Ответить | Цитировать Сообщить модератору |
o-o
Guest |
вот ето еще запустите после создания функцииdeclare @t table(id int); insert into @t values (1), (5); select * from @t cross apply dbo.udf_erik(id); |
9 авг 16, 17:59 [19521417] Ответить | Цитировать Сообщить модератору |
a_voronin Member Откуда: Москва Сообщений: 4807 |
ErikI, Запрос Оракловый покажите -- можно подумать |
9 авг 16, 19:51 [19521828] Ответить | Цитировать Сообщить модератору |
ErikI Member Откуда: Сообщений: 162 |
Вот решение с помощью hierarchyid.SELECT STUFF(CAST(( SELECT [text()] = '-' + [Field] FROM Table WHERE @child.IsDescendantOf(hid) = 1 FOR XML PATH(''), TYPE) AS VARCHAR(100)), 1, 2, '') |
12 авг 16, 17:53 [19535514] Ответить | Цитировать Сообщить модератору |
Между сообщениями интервал более 1 года. |
andreymx Member Откуда: Запорожье Сообщений: 54806 |
насколько я понял, уровень, на котором расположен каждый подчиненный манагера, тем же запросом тоже получить не удастся (аналог Ораклового Level) |
||
10 дек 17, 23:15 [21022654] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
|
||||
10 дек 17, 23:45 [21022762] Ответить | Цитировать Сообщить модератору |
andreymx Member Откуда: Запорожье Сообщений: 54806 |
подскажи на примереwith persons as ( select N'Степанов' cn, N'' manager union select N'Петров' , N'Степанов' manager union select N'Иванов' , N'Степанов' manager union select N'Сидоров' , N'Петров' manager union select N'Васькин' , N'Иванов' manager union select N'Петрыкин', N'Сидоров' manager ), t as ( select p.cn, p.manager from persons p where cn like N'%Степанов%' union all select p.cn, p.manager from persons p, t where p.manager = t.cn )select * from t
|
|||||||||||||||
10 дек 17, 23:56 [21022791] Ответить | Цитировать Сообщить модератору |
andreymx Member Откуда: Запорожье Сообщений: 54806 |
хм... вроде такwith persons as ( select N'Степанов' cn, N'' manager union select N'Петров' , N'Степанов' manager union select N'Иванов' , N'Степанов' manager union select N'Сидоров' , N'Петров' manager union select N'Васькин' , N'Иванов' manager union select N'Петрыкин', N'Сидоров' manager ), t as ( select p.cn, p.manager, 1 level from persons p where cn like N'%Степанов%' union all select p.cn, p.manager, t.level+1 from persons p, t where p.manager = t.cn )select * from t
|
||||||||||||||||||||||
11 дек 17, 00:00 [21022803] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
Собственно, пример получения уровней есть даже в хелпе, в первом же примере рекурсивного CTE |
||
11 дек 17, 08:37 [21023142] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |