Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Нужна помощь с рекурсией / 10 сообщений из 10, страница 1 из 1
10.03.2021, 09:35
    #40052158
Ramis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Здравствуйте, есть таблица со связанными ИД, пытаюсь через рекурсию связать их в группы. Но что то не могу правильно написать условие в запросе, что бы уйти от зацикливания и получения групп

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
INSERT INTO #t (Id_1, Id_2)
VALUES 
	(1, 2),	(1, 3),	(1, 4),	(4, 2),	(5, 6),	(6, 7),	(5, 10), (8, 9),
	(2, 1),	(3, 1),	(4, 1),	(2, 4),	(6, 5),	(7, 6),	(10, 5), (9, 8);

DECLARE @ID INT;
--SET @ID = 1

;WITH cte AS
(
  SELECT Id_1, Id_2, 0 AS lvl FROM #t WHERE Id_1 = @ID OR @ID IS NULL
  UNION ALL  
  SELECT t.Id_1, t.Id_2, c.lvl+1
  FROM #t  t 
  JOIN cte c ON c.Id_2 = t.Id_1
  --WHERE NOT EXISTS (SELECT 1 FROM #t WHERE t.Id_2 = c.Id_1 AND t.Id_1 = c.Id_2 )
  --and c.lvl in (1,2,3)
) 
SELECT Id_1, Id_2, lvl
FROM cte 
ORDER BY lvl
OPTION (MAXRECURSION 100)



В результате хотелось бы получить
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
group	Id_1	Id_2
A	1	2
A	1	3
A	1	4
A	4	2
B	5	6
B	5	10
B	6	7
C	8	9
...
Рейтинг: 0 / 0
10.03.2021, 09:45
    #40052160
Ramis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Feb 10 2012 19:39:15 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
...
Рейтинг: 0 / 0
10.03.2021, 09:52
    #40052164
Агрох
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Код: sql
1.
2.
3.
4.
INSERT INTO #t (Id_1, Id_2)
VALUES 
	(1, 2),	(1, 3),	(1, 4),	(4, 2),	(5, 6),	(6, 7),	(5, 10), (8, 9),
	(2, 1),	(3, 1),	(4, 1),	(2, 4),	(6, 5),	(7, 6),	(10, 5), (9, 8);



Получается что указатель один ссылается на указатель 2, указатель 2 ссылается на указатель 1, который в свою очередь ссылается на указатель 2, который ссылается на указатель 1....
Да, тут будет бесконечное зацикливание, т.к. оно предусмотрено исходными данными.

Либо убери вторую строчку из VALUES либо подумай над тем, как ещё ограничить вложенность.
...
Рейтинг: 0 / 0
10.03.2021, 10:45
    #40052182
Ramis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Агрох,
Если убрать вторую строку в VALUE, и запустить указав @ID =2 то ни чего не найдется.

если дописать условие
Код: sql
1.
 SELECT Id_1, Id_2, 0 AS lvl FROM #t WHERE Id_1 = @ID OR Id_2 = @ID OR @ID IS NULL



то получим результат где с 1 мы не вышли на 3:
1 2
4 2
...
Рейтинг: 0 / 0
10.03.2021, 11:13
    #40052192
Агрох
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Ramis, что такое @ID?
Если тебе надо вывести всю группу, даже если родитель ссылается на несуществующий объект - по которому ты и ищещь, то надо в условии прописывать что то типа: Id_1 = @ID or Id_2 = @ID.
Ещё раз, сейчас исходные данные сами по себе предполагают бесконечное зацикливание. Да ещё и, насколько я понял, ты роль Id_1 и Id_2 просто меняешь местами, т.к. по структуре выглядит всё так, что Id_2 - идентификатор элемента, а Id_1 - идентификатор родителя.
...
Рейтинг: 0 / 0
10.03.2021, 11:14
    #40052193
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
;WITH cte AS
(
  SELECT Id_1, Id_2, 0 AS lvl, '(' + cast(Id_1 as varchar(max)) + ')' as p FROM @t WHERE Id_1 = @ID OR @ID IS NULL
  UNION ALL  
  SELECT t.Id_1, t.Id_2, c.lvl+1, c.p + a.p
  FROM #t  t 
  JOIN cte c ON c.Id_2 = t.Id_1 cross apply
  (select '(' + cast(t.Id_1 as varchar(10)) + ')') a(p)
  where
   c.p not like '%' + a.p + '%'
) 
SELECT Id_1, Id_2, lvl, p
FROM cte 
ORDER BY lvl
OPTION (MAXRECURSION 100);
...
Рейтинг: 0 / 0
10.03.2021, 12:00
    #40052219
Ramis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
invm,
Спасибо большое. А как нибудь еще группы можно вывести?
...
Рейтинг: 0 / 0
10.03.2021, 12:12
    #40052228
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Ramis
А как нибудь еще группы можно вывести?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
;with cte as (
	select 
		t1.Id_1 as GrId 
		,t1.Id_1 
		,t1.Id_2 
		,cast('/'+cast(t1.Id_1 as varchar)+'/'+cast(t1.Id_2 as varchar)+'/' as varchar(max)) as path
	from #t t1
	where not exists(select 1 from #t t2 where t1.Id_1=t2.Id_2 and t1.Id_1>t2.Id_1)

	union all

	select
		cte.GrId
		,t1.Id_1
		,t1.Id_2
		,cte.path+cast(t1.Id_2 as varchar)+'/' as path
	from cte inner join #t t1 on cte.Id_2=t1.Id_1
	where cte.path not like '%/'+cast(t1.Id_2 as varchar)+'/%'
)
select 
	char(dense_rank()over(order by GrId)-1+ascii('A')) as Gr
	,Id_1
	,Id_2
from cte order by 1,2,3


GrId_1Id_2A12A13A14A24A42B56B510B67C89
...
Рейтинг: 0 / 0
10.03.2021, 13:09
    #40052269
Ramis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
court,
спасибо, но если запускать по определенному @ID, то отрабатывает не верно
...
Рейтинг: 0 / 0
11.03.2021, 11:00
    #40052543
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь с рекурсией
Ramis
court,
спасибо, но если запускать по определенному @ID, то отрабатывает не верно


если запускать "по определенному @ID", то непонятно про какие группы ты рассказываешь, так как это и будет одна группа (граф)

пс
я делал исходя из предположения, что у тебя несколько ненаправленных графов, так как выглядят исх.данные в сабже
и нужно разделить точки дуги по этим графам (группам) - так как выглядит "желаемый результат"
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Нужна помощь с рекурсией / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]