[英]Delete recursive records from same table
語境
ID | parent_id | 內容 | 時間結束 |
---|---|---|---|
1 | -1 | 根 | 11-08-2022 |
2 | 1 | 孩子 | 10-08-2022 |
22 | 2 | 葉子 | 09-08-2022 |
3 | 1 | 孩子 | 10-08-2022 |
11 | -1 | 根 | 10-08-2022 |
12 | 11 | 孩子 | 09-08-2022 |
約束
09-08-2022
end_time,其父 id 2 具有10-08-2022
end_time。問題
10-08-2022
的記錄11-08-2022
,所以我們不應該刪除該記錄; 記錄 id 2 和 3 也是如此。10-08-2022
技術
警告
首先,根據數據庫引擎,您的日期字符串表示可能並不理想。 我建議使用 YYYY-MM-DD,例如“2022-08-10”。
根據規則,刪除必須涉及頂級記錄,並且應該級聯到任何后代記錄。
由於樹的最大深度為 3,我建議自連接:
delete a
from mytable a
left join mytable b on a.parent_id = b.id
left join mytable c on b.parent_id = c.id
where coalesce(c.end_time, b.end_time, a.end_time) = '2022-08-10';
但是,引擎可能無法為此找到最佳執行計划,因此執行三個不同的 SQL 語句可能更有效,這些語句首先從第三級刪除記錄,然后是第二級,最后是第一級:
delete node
from mytable node
inner join mytable parent on node.parent_id = parent.id
inner join mytable top on parent.parent_id = top.id
where top.end_time = '2022-08-10'
and top.parent_id = -1;
delete node
from mytable node
inner join mytable top on node.parent_id = top.id
left join mytable child on child.parent_id = node.id
where top.end_time = '2022-08-10'
and top.parent_id = -1
and child.id is null;
delete node
from mytable node
left join mytable child on child.parent_id = node.id
where node.end_time = '2022-08-10'
and node.parent_id = -1
and child.id is null;
如果可以保證不會發生將子項添加到先前語句已從中刪除所有子項的父項的插入,則不需要在第二個和第三個查詢中進行與child
項的外連接。
不應需要第一個查詢中的top.parent_id = -1
條件,因為對於最多具有 3 個級別的樹,它保證為真。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.