Oracle sql对具有图形节点的表数据的分层或递归查询

Oracle sql对具有图形节点的表数据的分层或递归查询,sql,oracle,graph-theory,hierarchical-query,Sql,Oracle,Graph Theory,Hierarchical Query,这是我的表“graphtable”,它有图形节点。每个元组表示一条无向边 ╔═════════╦═════════╗ ║ NODEONE ║ NODETWO ║ ╠═════════╬═════════╣ ║ A ║ A ║ ║ A ║ A ║ ║ A ║ B ║ ║ A ║ B ║ ║ A ║ A ║ ║ C ║ D ║ ║ C ║ A

这是我的表“graphtable”,它有图形节点。每个元组表示一条无向边

╔═════════╦═════════╗
║ NODEONE ║ NODETWO ║
╠═════════╬═════════╣
║ A       ║ A       ║
║ A       ║ A       ║
║ A       ║ B       ║
║ A       ║ B       ║
║ A       ║ A       ║
║ C       ║ D       ║
║ C       ║ A       ║
║ D       ║ E       ║
║ A       ║ E       ║
║ D       ║ A       ║
║ G       ║ K       ║
║ G       ║ G       ║
║ K       ║ K       ║
║ K       ║ L       ║
║ L       ║ M       ║
║ Y       ║ M       ║
║ G       ║ L       ║
║ G       ║ L       ║
║ X       ║ Z       ║
║ D       ║ D       ║
║ I       ║ I       ║
╚═════════╩═════════╝
如您所见,此表中有四个不同的无向图

  • 节点(A、B、C、D、E)
  • 节点(L、K、G、M、Y)
  • 节点(一)
  • 节点(X,Z)
  • 我尝试了类似于下面发布的查询

    select nodeone,nodetwo
    from
    graphtable
    start with NODEONE='D'
    connect by nocycle prior nodeone=nodetwo
    
    我还可以使用递归查询遍历图

    但是,如果我从特定图形中的任何节点开始,我需要获取特定图形中涉及的所有元组。然而,我没有从我的任何查询中得到这个结果

    从nodeone='A'开始;似乎返回了所有边,但边“D-D”不存在。从nodeone='D'开始;似乎没有返回任何接近先前结果的结果

    请帮忙。。 我感谢你事先的帮助。 多谢各位

    每个元组表示一条无向边

    ╔═════════╦═════════╗
    ║ NODEONE ║ NODETWO ║
    ╠═════════╬═════════╣
    ║ A       ║ A       ║
    ║ A       ║ A       ║
    ║ A       ║ B       ║
    ║ A       ║ B       ║
    ║ A       ║ A       ║
    ║ C       ║ D       ║
    ║ C       ║ A       ║
    ║ D       ║ E       ║
    ║ A       ║ E       ║
    ║ D       ║ A       ║
    ║ G       ║ K       ║
    ║ G       ║ G       ║
    ║ K       ║ K       ║
    ║ K       ║ L       ║
    ║ L       ║ M       ║
    ║ Y       ║ M       ║
    ║ G       ║ L       ║
    ║ G       ║ L       ║
    ║ X       ║ Z       ║
    ║ D       ║ D       ║
    ║ I       ║ I       ║
    ╚═════════╩═════════╝
    
    您没有将其视为无向边-您将其视为有向边,因为您只检查
    previor nodeone=nodewo
    ,而不检查当前边的任一端是否可以与前一条边的任一端匹配

    Oracle 11g R2架构设置

    CREATE TABLE graphtable ( NODEONE, NODETWO ) AS
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'C', 'D' FROM DUAL UNION ALL
      SELECT 'C', 'A' FROM DUAL UNION ALL
      SELECT 'D', 'E' FROM DUAL UNION ALL
      SELECT 'A', 'E' FROM DUAL UNION ALL
      SELECT 'D', 'A' FROM DUAL UNION ALL
      SELECT 'G', 'K' FROM DUAL UNION ALL
      SELECT 'G', 'G' FROM DUAL UNION ALL
      SELECT 'K', 'K' FROM DUAL UNION ALL
      SELECT 'K', 'L' FROM DUAL UNION ALL
      SELECT 'L', 'M' FROM DUAL UNION ALL
      SELECT 'Y', 'M' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'X', 'Z' FROM DUAL UNION ALL
      SELECT 'D', 'D' FROM DUAL UNION ALL
      SELECT 'I', 'I' FROM DUAL;
    
    SELECT DISTINCT
           nodeone,
           nodetwo,
           rowid    -- Included as a unique id to differentiate edges with the
                    -- same start/end points.
    FROM   graphtable
    START WITH NODEONE = 'D'
    CONNECT BY NOCYCLE
       PRIOR nodeone IN ( nodeone, nodetwo )
    OR PRIOR nodetwo IN ( nodeone, nodetwo )
    ORDER SIBLINGS BY nodeone, nodetwo
    
    | NODEONE | NODETWO |                     ROWID |
    |---------|---------|---------------------------|
    |       A |       A | oracle.sql.ROWID@57528909 |
    |       A |       A | oracle.sql.ROWID@3d7f5c9c |
    |       A |       A | oracle.sql.ROWID@777a44ea |
    |       A |       B | oracle.sql.ROWID@1ca773d6 |
    |       A |       B | oracle.sql.ROWID@5f7ebb8a |
    |       A |       E | oracle.sql.ROWID@18229745 |
    |       C |       A | oracle.sql.ROWID@3d5acdbf |
    |       C |       D | oracle.sql.ROWID@1ac42001 |
    |       D |       A | oracle.sql.ROWID@30cc6a38 |
    |       D |       D | oracle.sql.ROWID@3cd85bdb |
    |       D |       E | oracle.sql.ROWID@57845eca |
    
    查询1

    CREATE TABLE graphtable ( NODEONE, NODETWO ) AS
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'C', 'D' FROM DUAL UNION ALL
      SELECT 'C', 'A' FROM DUAL UNION ALL
      SELECT 'D', 'E' FROM DUAL UNION ALL
      SELECT 'A', 'E' FROM DUAL UNION ALL
      SELECT 'D', 'A' FROM DUAL UNION ALL
      SELECT 'G', 'K' FROM DUAL UNION ALL
      SELECT 'G', 'G' FROM DUAL UNION ALL
      SELECT 'K', 'K' FROM DUAL UNION ALL
      SELECT 'K', 'L' FROM DUAL UNION ALL
      SELECT 'L', 'M' FROM DUAL UNION ALL
      SELECT 'Y', 'M' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'X', 'Z' FROM DUAL UNION ALL
      SELECT 'D', 'D' FROM DUAL UNION ALL
      SELECT 'I', 'I' FROM DUAL;
    
    SELECT DISTINCT
           nodeone,
           nodetwo,
           rowid    -- Included as a unique id to differentiate edges with the
                    -- same start/end points.
    FROM   graphtable
    START WITH NODEONE = 'D'
    CONNECT BY NOCYCLE
       PRIOR nodeone IN ( nodeone, nodetwo )
    OR PRIOR nodetwo IN ( nodeone, nodetwo )
    ORDER SIBLINGS BY nodeone, nodetwo
    
    | NODEONE | NODETWO |                     ROWID |
    |---------|---------|---------------------------|
    |       A |       A | oracle.sql.ROWID@57528909 |
    |       A |       A | oracle.sql.ROWID@3d7f5c9c |
    |       A |       A | oracle.sql.ROWID@777a44ea |
    |       A |       B | oracle.sql.ROWID@1ca773d6 |
    |       A |       B | oracle.sql.ROWID@5f7ebb8a |
    |       A |       E | oracle.sql.ROWID@18229745 |
    |       C |       A | oracle.sql.ROWID@3d5acdbf |
    |       C |       D | oracle.sql.ROWID@1ac42001 |
    |       D |       A | oracle.sql.ROWID@30cc6a38 |
    |       D |       D | oracle.sql.ROWID@3cd85bdb |
    |       D |       E | oracle.sql.ROWID@57845eca |
    

    CREATE TABLE graphtable ( NODEONE, NODETWO ) AS
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'B' FROM DUAL UNION ALL
      SELECT 'A', 'A' FROM DUAL UNION ALL
      SELECT 'C', 'D' FROM DUAL UNION ALL
      SELECT 'C', 'A' FROM DUAL UNION ALL
      SELECT 'D', 'E' FROM DUAL UNION ALL
      SELECT 'A', 'E' FROM DUAL UNION ALL
      SELECT 'D', 'A' FROM DUAL UNION ALL
      SELECT 'G', 'K' FROM DUAL UNION ALL
      SELECT 'G', 'G' FROM DUAL UNION ALL
      SELECT 'K', 'K' FROM DUAL UNION ALL
      SELECT 'K', 'L' FROM DUAL UNION ALL
      SELECT 'L', 'M' FROM DUAL UNION ALL
      SELECT 'Y', 'M' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'G', 'L' FROM DUAL UNION ALL
      SELECT 'X', 'Z' FROM DUAL UNION ALL
      SELECT 'D', 'D' FROM DUAL UNION ALL
      SELECT 'I', 'I' FROM DUAL;
    
    SELECT DISTINCT
           nodeone,
           nodetwo,
           rowid    -- Included as a unique id to differentiate edges with the
                    -- same start/end points.
    FROM   graphtable
    START WITH NODEONE = 'D'
    CONNECT BY NOCYCLE
       PRIOR nodeone IN ( nodeone, nodetwo )
    OR PRIOR nodetwo IN ( nodeone, nodetwo )
    ORDER SIBLINGS BY nodeone, nodetwo
    
    | NODEONE | NODETWO |                     ROWID |
    |---------|---------|---------------------------|
    |       A |       A | oracle.sql.ROWID@57528909 |
    |       A |       A | oracle.sql.ROWID@3d7f5c9c |
    |       A |       A | oracle.sql.ROWID@777a44ea |
    |       A |       B | oracle.sql.ROWID@1ca773d6 |
    |       A |       B | oracle.sql.ROWID@5f7ebb8a |
    |       A |       E | oracle.sql.ROWID@18229745 |
    |       C |       A | oracle.sql.ROWID@3d5acdbf |
    |       C |       D | oracle.sql.ROWID@1ac42001 |
    |       D |       A | oracle.sql.ROWID@30cc6a38 |
    |       D |       D | oracle.sql.ROWID@3cd85bdb |
    |       D |       E | oracle.sql.ROWID@57845eca |
    

    这可能没有帮助,但在关系数据库中实现图形并不理想。尤其是当存在针对其进行优化的DBMS时,例如Neo4J。如果你感兴趣的是图表,那么我建议你看看。谢谢。明白你的意思了。当然,我会看看Neo4j。谢谢你的回复。这种逻辑在所有用例中都是有效的,只是有一些小的变化,比如从NODEONE='E'或nodewo='E'开始。但是对于实际的表,它相当大,查询需要一段时间才能结束。我需要想办法加快速度。谢谢!!