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

Откуда: Feorina "Fury" 161
Сообщений: 4331
В простом виде он выглядит так:
(данный запрос - самая типичная рекурсия)
with Tree(ID, level, v1, v2, v3, v4)
as
(

	select 1, ID, FullName, null, null, null
	from dict_Tree
	where Parent_ID=null
	union all
	select
		ID,
		Tree.level+1,
		FullName, null, null, null
	from dictTree
	inner join Tree on Tree.ID=dict_Tree.Parent_ID
)

SELECT *
  FROM Tree

Выведет список имён из дерева и его уровень вложенности.
id level v1
1 1 Директор
2 2 Руководитель департамента Алёшин
3 2 Руководитель департамента Родин
4 3 Руководитель отдела Петров
5 4 Хреновый программист

Но! нужен вывод вот такой:
id level v1v2v3v4
1 1 Директор null null null
2 2 Директор Руководитель департамента Алёшин null null
3 2 Директор Руководитель департамента Родин null null
4 3 Директор Руководитель департамента Родин Руководитель отдела Петров null
5 4 Директор Руководитель департамента Родин Руководитель отдела Петров Хреновый программист
12 ноя 18, 18:27    [21732201]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с жёстким рекурсивным запросом))  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Charles Weyland,

если уровня только 4, то и рекурсия не нужна.
А если сколько хочешь, то - динамически формировать запрос.
12 ноя 18, 19:23    [21732275]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с жёстким рекурсивным запросом))  [new]
Cristiano_Rivaldo
Member

Откуда:
Сообщений: 323
WITH dict_Tree (id,parent_id,FullName)
AS 
(
	SELECT 1,NULL,'Директор'
	UNION ALL
	SELECT 2,1,'Руководитель департамента Алёшин'
	UNION ALL
	SELECT 3,1,'Руководитель департамента Родин'
	UNION ALL
	SELECT 4,3,'Руководитель отдела Петров'
	UNION ALL
	SELECT 5,4,'Хреновый программист'

),
Tree(ID, level, c_path)
as
(

	select id, 1, cast(FullName + ';' AS VARCHAR(MAX))
	from dict_Tree
	where Parent_ID IS  null
	union all
	select
		tr.ID,
		t.level+1,
		t.c_path + tr.FullName + ';'
	from Tree t INNER  JOIN dict_Tree tr ON tr.parent_id = t.id
		
)
SELECT	t.ID, t.LEVEL,
		MAX(CASE WHEN t.N = 1 THEN t.c_value END) v1,
		MAX(CASE WHEN t.N = 2 THEN t.c_value END) v2,
		MAX(CASE WHEN t.N = 3 THEN t.c_value END) v3,
		MAX(CASE WHEN t.N = 4 THEN t.c_value END) v4
FROM (
		SELECT t.ID, t.LEVEL,t.c_path,value  AS c_value,row_number() OVER (PARTITION BY t.ID,t.level ORDER BY (SELECT 1)) N
		  FROM Tree t
			CROSS  APPLY STRING_SPLIT(t.c_path, ';') 
		) t 
WHERE t.c_value <> ''
GROUP BY t.ID, t.LEVEL		
13 ноя 18, 09:52    [21732612]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с жёстким рекурсивным запросом))  [new]
Charles Weyland
Member

Откуда: Feorina "Fury" 161
Сообщений: 4331
круто.
спасибо))
13 ноя 18, 11:22    [21732760]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с жёстким рекурсивным запросом))  [new]
Cristiano_Rivaldo
Member

Откуда:
Сообщений: 323
Charles Weyland,

Самое интересное начнется когда c_path выйдет за границы VARCHAR(MAX). Тогда v1,v2,v3,v4 нужно будет определять с помощью рекурсии вверх.
13 ноя 18, 12:04    [21732810]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить