检索循环图数据,无需无限循环和重复

问题描述 投票:0回答:1

我需要查询这些记录以获取唯一的相关项目:

insert into items(child, parent) 
values (1, 2), (2, 3), (3, 5), (3, 4),
       (4, 5), (6, 7), (1, 8), (8, 1)

我需要传递输入,例如1 并获取相关项目的结果

 2 3 4 5 8

我尝试使用 SQL / CTE 但失败了。

所以,我需要任何带有 VB.NET 或 SQL 帮助的解决方案,并考虑大数据..

============ 添加查询

 WITH Alter_RC AS ( 
      SELECT sa1.child,
          sa1.parent,
          CAST(concat(LOWER( sa1.child), ',', LOWER( sa1.parent)) as  nvarchar(MAX)) as relpath
          FROM items sa1
          WHERE LOWER( sa1.child ) =   LOWER(  '1'  )
    UNION ALL
       SELECT  sa1.child,
           sa1.parent,
           CAST( concat(sa2.relpath, ',', sa1.parent) as nvarchar(MAX)) as relpath
           FROM Alter_RC as sa2 inner join items as sa1 on sa2.parent = sa1.child
           where LOWER( sa1.parent  ) NOT IN  (SELECT value FROM STRING_SPLIT(relpath, ','))
     )
     SELECT  parent FROM  Alter_RC  
     OPTION (MAXRECURSION 0);

输出

2 8 3 5 4 5
sql vb.net loops graph common-table-expression
1个回答
0
投票

这是在 SQL Server 中使用递归 CTE 的解决方案。请试一试。我不确定它会有多有效。但它肯定会给你你正在寻找的答案。

with main_cte as
    (
    select 
        case when parent > child then child 
            else parent end as child , 
        case when parent < child then child 
            else parent end as parent
    from items
    ) ,            
cte as
    (
        select  child , parent from main_cte as a
        union all
        select  a.child , b.parent from cte as a inner join main_cte as b on a.parent = b.child
    ),
base_cte as
    (
        select parent as child , child as parent from main_cte as a
    ),
next_cte as
    (
        select child , parent from base_cte as a
        union all
        select b.child , a.parent from next_cte as a inner join base_cte as b on a.child = b.parent
        union all
        select b.child , a.child from next_cte as a inner join base_cte as b on a.parent = b.parent
    ) , 
final_cte as
(
    select child as person  , parent as relatives from
    (
        select child , parent from cte 
        union all
        select child , parent from next_cte 
        where child <> parent
    ) as a
    group by child , parent
)
select person , string_agg(cast(relatives as varchar(1)) , ',') as realtives from final_cte group by person;

            
© www.soinside.com 2019 - 2024. All rights reserved.