sql - 在多个父级的封闭表中移动

标签 sql directed-acyclic-graphs transitive-closure-table

我有以下 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 > DC > D .

现在我正在使用以下查询,但它仅在每个节点只有 1 个父节点时才有效。
DELETE FROM `Closure`
WHERE `Descendant` IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node)
AND `Ancestor` NOT IN (SELECT `Descendant` FROM `Closure` WHERE `Ancestor`=@Node);

最佳答案

首先,我相信您的表格中有重复的条目。 (A,D)出现两次。二、去除边缘后(B,D) ,应保留以下路径:

  • 节点自映射:(A,A) , (B,B) , (C,C) , (D,D)
  • (A,B)
  • (A,C)
  • (A,D) ( 通过 C )

  • 因此,去除边缘 (B,D)在此示例中,所需要做的就是删除该行:
    Delete MyTable 
    Where Ancestor = 'B'
        And Descendant = 'D'
    

    一个闭包表仍然只是两个节点之间的映射关系。它的特别之处在于它将每个间接关系有效地映射为直接关系。边缘(B,D)简单地说,您可以从 B 获得至 D .仅这一行就没有说明您是如何到达 B 的。它也没有说明从 B 获得多少个节点。至 D ;它只是说你可以从 B 得到至 D .因此,没有为 A > B > D 列出边。本身。相反,所捕获的只是您可以从 A 获得的信息。至 B来自 AD即使边缘 (B,D) 仍然如此已移除。

    关于sql - 在多个父级的封闭表中移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9641932/

    相关文章:

    sql - 在 Oracle 中连接表(多个外连接)

    php如何比较一天与近结束时间的比

    sql - 唯一标识符 (GUID) 上的聚合函数

    sql - 不允许 UPDATE,因为该语句更新 View "table_name",该 View 参与联接并具有 INSTEAD OF UPDATE 触发器

    python - Airflow 在 1 分钟后终止了我的任务

    algorithm - 关键路径与最长路径的关系

    mysql - 使用闭包表时,我将使用什么查询来获取兄弟记录?

    ruby-on-rails - 使用闭包表模式实现版本历史

    python - 如何定义 STFP Operator 在 Airflow 上的操作?

    python - SQLAlchemy是否支持 "closure tables?"