create table the_table (
  id integer, root_id integer, parent_id integer, status text, ts timestamp, comment text);
insert into the_table values
(1, null, null, 'COMPLETE', now()-'92d'::interval, '>90 days old, complete, standalone'),
(2, null, null, 'COMPLETE', now()-'92d'::interval, '>90 days old, complete, root of 3,4'),
(3, 2,    null, 'COMPLETE', now()-'92d'::interval, '>90 days old, complete, child of 2, parent of 4'),
(4, 2,    3,    'OPEN',     now()-'92d'::interval, '>90 days old, open, child of 2,3'),
(5, null, null, 'COMPLETE', now()-'92d'::interval, '>90 days old, complete, root of 6,7'),
(6, 5,    null, 'COMPLETE', now()-'92d'::interval, '>90 days old, complete, child of 5, parent of 4'),
(7, 5,    6,    'COMPLETE', now()-'10d'::interval, '<=90 days old, complete, child of 5,6' )

从表中删除所有记录,

  • 超过90天
  • 处于COMPLETE状态.

如果行具有root_idparent_id并且是OPEN, 则不应删除第root_id行和第parent_id行.

在上表中,应删除包含id=1的行.

id=2id=3COMPLETE和超过90天,但由于id=4OPEN,具有root_id=2parent_id=3,这三行(id in (2,3,4))不应被删除.

id=5id=6id=7都是COMPLETE,但id=7不超过90天,有root_id=5parent_id=6,所以这三行(id=5id=6id=7)不应该被删除.

我try 了多种方式进行内部查询 但是我不能为这个场景编写一个查询.

DB<>Fiddle

推荐答案

  1. 您只想删除COMPLETE101&>90天的行.
  2. 如果某行满足1.删除条件,但它是因为仍然是OPEN或太年轻而无法删除的行的子行、父行或根行,则不希望删除任何链接的行.对称:锁定的父项锁定子对象,锁定的子项锁定父项.
DELETE FROM the_table t1
WHERE 'COMPLETE'=status AND now()-ts > '90d'::interval
AND NOT EXISTS (SELECT FROM the_table AS t2
                WHERE (   t1.id IN(t2.root_id,t2.parent_id)
                       OR t2.id IN(t1.root_id,t1.parent_id) )
                  AND (   'OPEN'=t2.status
                       OR now()-t2.ts <= '90d'::interval    )  )
RETURNING *;
id root_id parent_id status ts comment
1 null null COMPLETE 2023-08-09 11:14:25.445328 >90 days old, complete, standalone

我在this db<>fiddle demo中添加了更多的测试用例.最后,有一个 case 需要澄清:一个具有两个子元素的可拆卸父级,一个不可拆卸,一个可拆卸.如果允许删除可移除子对象,而父对象保留不可移除子对象,则此操作有效.如果您希望保留整个图形/族,直到所有 node /成员都可删除,则需要recursive CTEroutine来遍历图形.

Sql相关问答推荐

Oracle SQL对列进行汇总并在列表底部显示总计

SQL(PostgreSQL)从条件创建点表

从以前的非空值行中获取值

PostgreSQL 9.6嵌套的INSERT/RETURN语句的CTE性能低得令人无法接受

NULL-生成的列中连接的字符串的输入

正在try 从SQL获取最新的ID和一个唯一名称

仅当交叉应用返回单值时才更新记录

重用传递给 node 的参数-postgres upsert查询

对于多字节字符,SQL Server中的DATALENGTH返回1字节

我如何才能在付款人单列中拉出只有9个付款人单的人?

WooCommerce产品的SQL查询:获取sku和产品标签

无法访问级联删除导致的触发器中已删除的外键记录

不存在记录的国外关键点

从重复值中获取最新值

同时插入和更新记录

AdventureWorks 查询

Postgresql 生成器列导致语法错误

删除重复记录但保留最新的SQL查询

Oracle SQL 从多个条件中 Select 但具有相同的 id

从 Pyspark 转换为具有多个分组条件的语句时的情况