问题描述
我有以下形式的关系数据:
Parent ID ParentName ParentType RelatedToID RelatedToName RelatedType
----------------------------------------------------------------------------
1 A Business 2 B Individual
1 A Business 4 D Business
1 A Business 3 C Business
1 A Business 6 F Business
1 A Business 3 C Business
1 A Business 9 I Business
1 A Business 9 I Business
1 A Business 3 C Business
1 A Business 12 L Business
1 A Business 5 E Business
2 B Individual 1 A Business
2 B Individual 3 C Business
2 B Individual 3 C Business
2 B Individual 6 F Business
2 B Individual 3 C Business
2 B Individual 4 D Business
2 B Individual 4 D Business
3 C Business 1 A Business
3 C Business 1 A Business
3 C Business 2 B Individual
3 C Business 10 J Business
3 C Business 6 F Business
3 C Business 14 N Business
3 C Business 4 D Business
3 C Business 7 G Business
3 C Business 1 A Business
3 C Business 2 B Individual
4 D Business 2 B Individual
4 D Business 3 C Business
4 D Business 3 C Business
4 D Business 10 J Business
4 D Business 1 A Business
4 D Business 1 A Business
4 D Business 7 G Business
5 E Business 1 A Business
5 E Business 1 A Business
6 F Business 2 B Individual
6 F Business 1 A Business
6 F Business 3 C Business
6 F Business 3 C Business
6 F Business 1 A Business
7 G Business 3 C Business
7 G Business 4 D Business
7 G Business 3 C Business
7 G Business 3 C Business
8 H Individual 9 I Business
8 H Individual 9 I Business
9 I Business 1 A Business
9 I Business 8 H Individual
10 J Business 3 C Business
10 J Business 3 C Business
10 J Business 13 M Business
10 J Business 3 C Business
10 J Business 4 D Business
10 J Business 11 K Individual
11 K Individual 10 J Business
11 K Individual 13 M Business
11 K Individual 10 J Business
11 K Individual 13 M Business
12 L Business 1 A Business
13 M Business 11 K Individual
13 M Business 10 J Business
我正在使用DiagrammeR根据此数据制作关系图。我需要在sql中转换此数据以馈入graphviz。即:
- 最终表中的列,其形式为ParentID“->” RelatedToID(例如“ A-> B”)
- 排除任何多余的向后关系,即A-> B&B-> A应减少为A-> B
在我的数据准备步骤中,我愿意进入关系树5级。最终,上述示例应简化为:
ReadySet
A->B
A->D
A->C
A->F
A->I
A->L
A->E
B->C
B->F
B->D
C->J
C->F
C->N
C->D
C->G
D->J
D->G
H->I
J->M
J->K
K->M
在GraphViz中产生的结果:
我尝试过的事情和我遇到的困难:
我从定义ParentType ='Individual'的父母开始 然后,我使用自我加入来获得行级的层次结构。
我想要(而且似乎做不到)的是,如果用户做出的选择名称包含在关系树的宽度内,则生成一个sql表,该表将产生 ReadySet 例如,如果选择了A,则 ReadySet ;如果选择了M,则 ReadySet …。整个数据集中显然有更多的父ID /名称。
解决方法
您需要一个表格来定义节点之间的边缘及其方向。
create table edges (
from_id bigint not null references nodes(id),to_id bigint not null references nodes(id),primary key(from_id,to_id);
);
这里的“节点”是表实际保存数据的任何地方。
如果这种关系是两种方式,我们需要行,一个用于A-> B,另一个用于B-> A。
然后执行recursive CTE来查找所有匹配的行。
with recursive ready_set as (
select *
from edges
where from_id = ?
union
select e.*
from edges e
inner join ready_set rs on e.from_id = rs.to_id
)
select *
from ready_set;
联合的第一部分是开始条件,第二部分是与CTE联接的递归。
例如,如果我们这样设置边线:
1 <-> 2 <-> 3 -> 4
1 <-> 5 <- 6
insert into edges values
(1,2),(2,1),3),(3,4),(1,5),(5,(6,5);
除了6是通往5的一种方法外,其他所有东西之间都有一条路径。如果我们要求5,我们将得到除6、5以外的所有边。如果我们要求4,我们将一无所获,因为4没有传出连接。
如果我们select distinct to_id from ready_set;
从5开始,我们只会得到节点ID 1、2、3、4和5。否6。