我有以下DAG在关闭工作台移动与多亲
A --> B
| |
v v
C --> D
这里是封闭表
| Ancestor | Descendant | Depth |
---------------------------------
| A | A | 0 |
| A | B | 1 |
| A | C | 1 |
| A | D | 2 |
| A | D | 2 |
| B | B | 0 |
| B | D | 1 |
| C | C | 0 |
| C | D | 1 |
| D | D | 0 |
我怎么会去不还删除删除路径B > D
(从而消除A > B > D
) A > C > D
和C > D
。
现在我正在使用下面的查询,但它只适用于每个节点只有1个父项。
DELETE FROM `Closure`
WHERE `Descendant` IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`[email protected])
AND `Ancestor` NOT IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`[email protected]);
重复(A,D)实际上是这个问题的根源 - 它存在表明,在一个闭包表中,你将有一个(A,D)由ABD和ACD引起。如何检测另一条路径在此钻石中相交而不是删除(A,D)?最好只使用SQL并且只给出边(B,D)。 – NtscCobalt 2013-05-29 20:56:38
@NtscCobalt - 在那里有两次'(A,D)'是没有意义的。闭包表不会描述*一个节点如何与另一个节点连接;只有*表示一个节点与另一个节点相连。因此,如果表中有((A,D)),从A到D的路径是否是A> B> C> E> .....> X > Y> D'或'A> D'。这才是重点。封闭表格为您节省了每次计算该路径的麻烦。如果您试图捕获从一个节点到另一个节点的路径,那么封闭表不是解决方案。而是将图形存储在边缘表中并计算路径。 – Thomas 2013-05-29 21:32:14
啊,是啊,我很难记住为什么我问这个问题说实话。我不记得我们决定做什么解决方案。我认为最初的目的是找出一种从(B,D)中删除边缘的方法,并删除由此引起的闭合表中的所有条目,而不会意外删除仍然存在的边缘。我可以立即想到的唯一解决方案是从您只知道一步的节点重建整个闭合表。 – NtscCobalt 2013-05-29 21:35:35