Ciclos em gráficos levam a loops infinitos em CTEs.
Lidar com eles no Postgres é simples.
Desde 8.0, o MySQL também permite CTEs. Como posso detectar ciclos e loops infinitos em MySQL CTEs?
O objetivo não é interromper a consulta após 1000 ou qualquer número de iterações, mas realmente tratá-la no código (por exemplo, coletando em um array a lista de nós visitados e tendo uma condição de desigualdade para evitar loops).
Ou existem opções "incorporadas" para lidar com isso, como cycle COLNAME
nos CTEs do Postgres?
Meu código atual se parece com isso
with recursive circle as (
select friend2, name2, 0 as depth from my_view1 where friend1 = 1
union
select m.friend2, m.name2, c.depth+1 from my_view1 m
inner join circle c on c.friend2 = m.friend1)
select * from circle where circle.depth < 2;
As tabelas subjacentes podem ser criadas com:
create table people (person_id integer primary key, name varchar(20) not null);
insert into people (person_id, name) values (1, 'tom'), (2, 'dick'), (3, 'harry'), (4, 'susan'), (5, 'mary'), (6, 'jill');
create table friends (friend1 integer references people (person_id), friend2 integer references people (person_id), primary key (friend1, friend2));
insert into friends (friend1, friend2) values (1,2), (2, 3), (3, 4), (5, 6);
insert into friends (friend1, friend2) values (2,1), (3,2), (4,3), (6,5);
create view my_view1 as select f.friend1, p.name as name1, f.friend2, p1.name as name2 from friends f join people p on p.person_id = f.friend1 join people p1 on p1.person_id = f.friend2 ;
Neste caso, UNION DISTINCT em CTE é suficiente para prevenir o ciclo:
violino
se você precisar dos dados de amizade para um usuário específico ou para uma lista de usuários, edite/descomente a condição na consulta base do CTE.
Se você precisar usar esta consulta como uma exibição, adicione
CREATE VIEW collect_friends AS
no início.