Oracle hierarchical query on non-hierarchical data

后端 未结 3 1164
无人及你
无人及你 2021-02-07 13:00

I hava data in an Oracle table that is organized as a graph that can contain cycles (see example).

     CREATE TABLE T (parent INTEGER, child INTEGER)
                   


        
3条回答
  •  一个人的身影
    2021-02-07 13:13

    What is your expected maximum depth to reach any child node?

    If it's relatively small, you could loop down, while checking for nodes you have already visited, in a manner something like this...

    (Note, I'm not an Oracle expert so this is closer to pseudo code with a little real SQL mixed in)

    CREATE TABLE myMap (parent INT, child INT);
    
    INSERT INTO myTable SELECT NULL, 2 FROM DUAL;
    
    WHILE (SQL%ROWCOUNT > 0)
    LOOP
    
      INSERT INTO
        myMap
      SELECT DISTINCT
        dataMap.parent,
        dataMap.child
      FROM
        myMap
      INNER JOIN
        dataMap
          ON myMap.child = dataMap.parent
      WHERE
        NOT EXISTS (SELECT * FROM myMap WHERE parent = dataMap.parent)
    
    END LOOP;
    

    Depending on performance, you may also want a depth field in myMap; optimising the join so as to only join on the most recent nodes. This would imply two indexes; one for the JOIN (depth) and one for the NOT EXISTS (parent).

    EDIT

    Added the DISTINCT key word, to avoid the following case...
    - Node 2 maps to 3 and 4
    - Nodes 3 and 4 both map to node 5
    - All children of node 5 would now be processed twice

    GROUP BY, or many other options, can be used to cater for this instead of DISTINCT. It's just that the NOT EXISTS on it's own is not sufficient.

提交回复
热议问题