首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在SQL中对分层数据建模的最佳方法是什么?

在SQL中对分层数据建模的最佳方法是什么?
EN

Stack Overflow用户
提问于 2020-09-22 20:20:37
回答 1查看 269关注 0票数 0

我有表格中的关系数据:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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 =“个人”的父母开始,然后我使用自己的连接在行级别上获得哈吉制。

我想要的(而且似乎不能这样做)是,如果用户生成一个包含在关系树宽度内的选择名称,那么生成一个ReadySet的SQL表,也就是说,如果A被选中,那么ReadySet,或者如果M被选中,则ReadySet…显然,我的整个数据集中有更多父ID/名称。

EN

回答 1

Stack Overflow用户

发布于 2020-09-22 21:22:33

您需要一个表来定义节点之间的边缘及其方向。

代码语言:javascript
运行
复制
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。

然后执行一个递归CTE来查找所有匹配的行。

代码语言:javascript
运行
复制
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连接的递归。

例如,如果我们像这样设置边缘:

代码语言:javascript
运行
复制
1 <-> 2 <-> 3 -> 4
1 <-> 5 <- 6

insert into edges values
  (1, 2), (2, 1),
  (2, 3), (3, 2),
  (3, 4),
  (1, 5), (5, 1),
  (6, 5);

每件事都有一条彼此之间的路,除了6,这是通往5的一条路。如果我们要求5,我们将得到除6,5以外的所有边。如果我们要求4,我们将什么也得不到,因为4没有传出连接。

如果我们从5开始select distinct to_id from ready_set;,我们将得到节点ID 1、2、3、4和5. No 6。

试试看

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64017136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档