簡體   English   中英

從同一個表中刪除遞歸記錄

[英]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
  • 用於可視化目的在此處輸入圖像描述
  • 表有以下字段
    • ID
    • parent_id 表示父記錄
    • 內容
    • end_time 用於分析目的

約束

  • 層次結構級別可以 go 最多只能到三個級別(根據樣本數據),最小到一個級別
  • 任何記錄的 end_time 都將低於其父記錄,例如,記錄 id 22 具有09-08-2022 end_time,其父 id 2 具有10-08-2022 end_time。

問題

  • 我們需要為這張桌子做家務
  • 我們需要根據根記錄 end_time 的 end_time 刪除記錄。
  • 假設我們需要刪除 end_date 為10-08-2022的記錄
  • 記錄 id 22 的根記錄 id 為 1,因為它的 end_time 是11-08-2022 ,所以我們不應該刪除該記錄; 記錄 id 2 和 3 也是如此。
  • 唯一要刪除的記錄是記錄 ID 11 和 12,因為它們的 end_time 是10-08-2022

技術

  • SQL服務器
  • MYSQL

警告

  • 表將有大約 3000 萬條記錄,因此我們需要優化查詢,因此我們的查詢不應長時間鎖定表

首先,根據數據庫引擎,您的日期字符串表示可能並不理想。 我建議使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM