PostgreSQL:删除行和其他行并引用已删除的行

wer*_*her 3 sql postgresql recursion sql-delete

我正在使用 PostgreSQL,我有一个family这样的表:

+----+-------+-----------+
| id | name  | parent_id |
+----+-------+-----------+
|  1 | adam  |         0 |
|  2 | eva   |         0 |
|  3 | peter |         2 |
|  4 | pan   |         3 |
+----+-------+-----------+
Run Code Online (Sandbox Code Playgroud)

现在当我删除这个人时,我也希望孩子们被删除。例如,从列表中WHERE name='peter'删除'peter'和删除'pan'。当我删除'eva',她,'peter'并被'pan'删除。

现在我想删除初始行并从删除的行中获取 id。然后我会再次删除,直到现在 id 被返回。请注意,一个人只有一个父母,但可以有几个孩子。

SQL 中有没有一种巧妙的方法来解决这个问题?如果没有,如何取回所有已删除行的 ID?

a_h*_*ame 5

最好的解决方案是创建一个用on delete cascade. 这需要NULL在 parent_id 列中存储一个值而不是一个神奇的“零”:

create table family 
(
  id int primary key, 
  name varchar(5), 
  parent_id int, 
  foreign key (parent_id) references family on delete cascade
);
Run Code Online (Sandbox Code Playgroud)

那么你只需要:

delete from family
where name = 'peter';
Run Code Online (Sandbox Code Playgroud)

在线示例


如果要转换现有的表和数据,可以这样做:

--- change all zeroes to NULL
update family 
  set parent_id = null
where parent_id = 0;

-- add a primary key in order to be able to create a foreign key
alter table family add primary key (id);

-- add the foreign key 
alter table family 
  add foreign key (parent_id) references family (id)
  on delete cascade;
Run Code Online (Sandbox Code Playgroud)