【问题标题】:CTE to show all transitively related elements (siblings)CTE 显示所有传递相关的元素(兄弟)
【发布时间】:2022-02-16 06:21:03
【问题描述】:

我有一个带有子 ID 列 Child1 和 Child2 的 Siblings 表:

Child1 Child2
1 2
2 3
4 6
5 1
create table Siblings (Child1 int, Child2 int)
insert into Siblings values (1,2)
insert into Siblings values (2,3)
insert into Siblings values (4,6)
insert into Siblings values (5,1)

对于每一行,Child1 是 Child2 的兄弟姐妹(反之亦然,因为兄弟姐妹关系是对称的),例如1 是上表第一行中 2 的兄弟。同样由于 1 是 2 的兄弟,而 2 是 3 的兄弟,那么 1 也是 3 的兄弟(兄弟关系是传递的)。使用 TSQL 如何显示上表中明显的所有兄弟关系?我假设这里需要使用递归公用表表达式 (CTE)。我今天才开始深入研究 CTE,所以我对如何去做这件事有点困惑。我想看到这样的输出:

Child Sibling
1 2
1 3
1 5
2 1
2 3
2 5
3 1
3 2
3 5
4 6
5 1
5 2
5 3
6 1

或者一个选择语句,它将简单地显示作为给定子 ID 的兄弟的所有子 ID。非常感谢任何帮助,谢谢!

【问题讨论】:

  • 根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。
  • 我自己为解决这个问题所做的所有尝试,但遗憾的是我没有保存,而是基于对 CTE 的非常有限的理解,并且相信涉及递归而不是纯基于集合的方法的程序构造会被需要。我在网上看到了很多模糊相似的谱系/血统类型的问题,但没有涉及到一个表格,你只知道对于每一行,第 1 列与第 2 列传递相关。

标签: sql sql-server common-table-expression


【解决方案1】:

不知道是否有使用 CTE 的好方法。这是可行的,如果没有别的,您可以使用它来测试其他解决方案...

Drop Table If Exists #Siblings
Create Table #Siblings(Child1 Int, Child2 Int)
Insert Into #Siblings values (1,2),(2,3),(4,6),(5,1)

Drop Table If Exists #Res
Create Table #Res(C1 Int, C2 Int)

Insert Into #Res(C1, C2)
Select Child1, Child2 From #Siblings
Union
Select Child2, Child1 From #Siblings

Declare @RC Int = 1
While @RC > 0
Begin
  Insert Into #Res(C1, C2)
  Select R1.C1, R2.C2
  From
    #Res As R1
    Inner Join #Res As R2
      On R1.C2 = R2.C1
  Where Not Exists(Select *
                   From #Res As NoDupes
                   Where NoDupes.C1 = R1.C1 And NoDupes.C2 = R2.C2)
  Set @RC = @@ROWCOUNT
End
Select Distinct * From #Res Where C1 != C2 Order By 1, 2

【讨论】:

  • 谢谢斯图。这已经处理了我知道的所有案件。
猜你喜欢
  • 2016-10-11
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
相关资源
最近更新 更多