【问题标题】:Find the columns values connectivity查找列值连接
【发布时间】:2019-10-10 09:00:31
【问题描述】:

我有下表包含示例数据:

表:tbl_nodes

create table tbl_nodes
(
    nod1 varchar(50),
    nod2 varchar(50),
    nod_lenght float
);

样本数据:

insert into tbl_nodes values('A','B',1600); 
insert into tbl_nodes values('G','H',45000);
insert into tbl_nodes values('B','C',2300);
insert into tbl_nodes values('C','D',2640);
insert into tbl_nodes values('B','D',2840);
insert into tbl_nodes values('C','E',2940);
insert into tbl_nodes values('D','F',2340);
insert into tbl_nodes values('M','N',9000);
insert into tbl_nodes values('E','A',100000);

预期结果

Connectivity        Total_Length
----------------------------------
A-B-C-D-F           8880
A-B-C-E-A           106840
A-B-D-F             6780

注意:我正在尝试找出节点的连通性和节点之间的长度总和。

我尝试了以下查询:

我的尝试

;WITH CTE AS
(
    SELECT nod1,nod2 ,sum(nod_lenght) as Total_length
    from tbl_nodes T1
    where EXISTS (select 1 from tbl_nodes T2 where T1.nod2 =T2.nod1) OR 
    EXISTS (select 1 from tbl_nodes T3 WHERE T1.nod1 =T3.nod2)
    GROUP BY nod1,nod2 
)
SELECT STUFF((select '-'+ case when c1.nod2 = c2.nod1 then c1.nod1 else c2.nod2 end
              from CTE c1 
              where c1.nod2 =c2.nod1 or c1.nod1 =c2.nod2
              for xml path('')),1,1,''),Total_length
FROM CTE c2

无法获得预期的结果。

【问题讨论】:

  • 您能解释一下您的预期结果吗?为什么 A/B 有 3 行不同的行?它看起来像分层数据,但如果是,A/B 加入哪一行,B 有 2 行? B 加入哪个 A/BB 有 2 行?看起来你也有一个循环引用:A->B->C->E->A->B->C->E-> A->...
  • @Larnu,我的错,更正了示例数据。
  • 新数据并不能回答我的任何问题。你没有回答它是否是分层的,如果它有 still 2 行B(和C),仍然存在循环引用。
  • @Larnu,不,它根本不是分层数据,任何节点都可以与任何节点建立连接。我只需要找出从源A 到端节点的FA 的连接(这里端节点A 用作循环引用)。
  • 所以我回到我原来的陈述“你能解释一下你的预期结果吗?”你没有解释你的逻辑,我们不是读心者我'我害怕。您的问题将被不了解您或您的系统的人阅读。我们需要了解您拥有的数据、您想要的数据、从 A 到 B 实现的逻辑。没有这些,我们无能为力你,因为我们不知道你想要什么。

标签: sql sql-server sql-server-2012


【解决方案1】:

我很确定您需要递归 CTE。但是,您的示例结果没有意义。

以下内容基本上可以满足您的要求:

with cte AS (
      select nod1, nod2, nod_length as Total_length,
             convert(varchar(max), concat('-', nod1, '-', nod2, '-')) as nodes, 1 as lev
      from tbl_nodes n
      where nod1 = 'A'
      union all
      select cte.nod1, n.nod2, cte.Total_length + n.nod_length,
             convert(varchar(max), concat(cte.nodes, n.nod2, '-')) as nodes, lev + 1
      from cte join
           tbl_nodes n
           on cte.nod2 = n.nod1
      where nodes not like concat('%-', n.nod2, '-%') 
     )
select nodes, total_length
from cte
where not exists (select 1
                  from cte cte2
                  where cte2.nodes like concat(cte.nodes, '_%')
                 );

Here 是一个 dbfiddle。

【讨论】:

  • 工作正常,你能调整查询吗?它继续运行4000 记录。
  • @MAK 。 . .不幸的是,除了在nod1 上建立索引之外,您无能为力。如果长时间运行,您必须有一棵宽树。我怀疑你的结果集非常大。
  • 你能帮我解决这个问题吗:stackoverflow.com/questions/58832990/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多