如何找到图形的末端节点?

时间:2014-05-17 20:34:45

标签: sql oracle

我的代码当前输出图表中遍历的所有节点。

CREATE TABLE DAG(
  pid NUMBER,
  cid NUMBER,
  PRIMARY KEY(pid, cid)
);

WITH Ancestor(ancestor, descendant) AS 
(   SELECT d.pid, d.cid
    FROM DAG d
    UNION ALL
    SELECT d.pid, a.descendant
    FROM Ancestor a  
    JOIN DAG d
    ON d.cid = a.ancestor
)   
SELECT * FROM Ancestor;

如何让它显示图表的所有终端节点?

2 个答案:

答案 0 :(得分:1)

怎么样;

SELECT * FROM dag WHERE cid NOT IN (SELECT pid FROM dag)

基本上它只是查找所有节点并删除所有节点,这些节点是另一个节点的父节点。

编辑:在您编辑问题之后,您似乎想要递归地找到所有没有孩子的父母和祖父母;

WITH Ancestor(grandparent, parent, child) AS 
(   SELECT 0, d.pid, d.cid FROM DAG d WHERE pid=1
    UNION ALL
    SELECT a.parent, a.child, d.cid
    FROM Ancestor a  
    LEFT JOIN DAG d
      ON d.pid = a.child
    WHERE a.child IS NOT NULL
)   
SELECT grandparent ancestor, parent descendant
FROM Ancestor
WHERE ancestor.child IS NULL;

你的基本案例是根节点(pid = 1),使用左连接递归查找所有没有孩子的祖父母/父母,并将它们显示为祖先/后代。

An SQLfiddle to test with

答案 1 :(得分:1)

评论的回答:

WITH Ancestor(ancestor, leaf) AS 
(   SELECT d.pid, d.cid
    FROM DAG d
    UNION ALL
    SELECT  d.pid, a.leaf
    FROM    Ancestor a
    JOIN    DAG d
        ON d.cid = a.ancestor
)   
SELECT leaf, ancestor 
FROM Ancestor a1
WHERE NOT EXISTS (
   select 1 from ancestor a2 
   where a2.ancestor = a1.leaf
)