sql - sql - 在具有多个相同路径的闭包表中删除
问题描述
我有以下层次结构:
A -> E -> C -> D
|
|
|-> B -> D
这是我想出的关闭表:
| Ancestor | Descendant | Depth |
| A | A | 0 |
| B | B | 0 |
| C | C | 0 |
| D | D | 0 |
| E | E | 0 |
| A | E | 1 |
| A | B | 1 |
| A | C | 2 |
| E | C | 1 |
| A | D | 3 |
| E | D | 2 |
| C | D | 1 |
| A | D | 2 |
| B | D | 1 |
我想删除 and 之间的链接B
,D
因此我想删除 and 之间的链接A
(D
深度之一2
)。问题是我不想删除 和 之间的链接,A
因为D
我3
没有删除 和 之间的C
链接D
。
目前,这里是列出我要删除的链接的 SQL 语句:
SELECT link.ancestor, link.descendant, link.depth
FROM closure_table p,
closure_table link,
closure_table c
WHERE p.ancestor = link.ancestor
AND c.descendant = link.descendant
AND p.descendant = B
AND c.ancestor = D;
但是这个语句给了我不想删除的行:
| Ancestor | Descendant | Depth |
| A | D | 2 |
| A | D | 3 | <- As said before, I want to keep this one
| B | D | 1 |
解决方案
您可以选择所有相同祖先-后代对中深度最小的祖先-后代对:
with edges(s, e) as (
-- the pairs to be removed
select 'A', 'D'
union all
select 'B', 'D'
),
n_l as (
select c.* from closure c where c.ancestor != c.descendant
)
select c.* from n_l c where exists (select 1 from edges e where e.s = c.ancestor and e.e = c.descendant)
and c.depth = (select min(c1.depth) from n_l c1 where c1.ancestor = c.ancestor and c1.descendant = c.descendant);
输出:
祖先 | 后裔 | 深度 |
---|---|---|
一种 | D | 2 |
乙 | D | 1 |
推荐阅读
- java - Twilio Android,接听电话时收到“onCancelledCallInvite:CallException code:31008”
- javascript - 点击期间事件重复多次
- python - 使用 pd.json_normalize 展平字典
- javascript - 如何在 ChartJS - AngularJS 上设置边框宽度?
- android - react-native-maps 未完全加载
- python - 作为列表理解中的集合的动态表达式是否只评估一次?
- r - data.table 列表列上的元编程映射
- sql-server - SQL Server 爱尔兰 FADA 未正确显示
- sql - 转义结束报价 Oracle SQL
- mysql - 如何选择每个ID对应的3个最新日期的所有数据?