在SQL中创建子组网络连接

时间:2019-01-14 15:09:26

标签: sql sql-server tsql

我正在寻找一种完成任务的方法。

带有连接网络表: connection_from connection_to

| connection_from | connection_to|
|:----------------|-------------:|
| A               |     B        |
| A               |     C        |
| G               |     C        |
| D               |     F        |

我想创建一个脚本来创建所有以任何方式连接到例如的值的列表。 A.对于我的表,它应该创建一个具有以下值的表:A,B,C和G-与G的连接不是直接的-这是由于连接A-> C,C-> G。

该连接通过两种方式起作用:A-> B和B-> A之间没有区别。

我正在处理大型表,因此代码的效率也很重要。

1 个答案:

答案 0 :(得分:2)

这是一个遍历图的问题-这意味着递归CTE。我发现挑战在于保留已访问节点的列表,以防止无限递归。

以下通过将访问的节点填充到字符串中来解决此问题:

with t as (
      select v.*
      from (values ('A', 'B'), ('A', 'C'), ('G', 'C'), ('D', 'F')) v(cfrom, cto)
     ),
     edges as (
      select cfrom, cto from t 
      union  -- on purpose to remove duplicates
      select cto, cfrom from t 
     ),
     cte as (
      select 'A' as c, convert(varchar(max), ',A,') as cs
      union all
      select e.cto, cs + e.cto + ','
      from cte join
           edges e
           on e.cfrom = cte.c
      where cte.cs not like '%,' + e.cto + ',%'
     )
select *
from cte;

Here是db <>小提琴。