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_id
或parent_id
,并且是OPEN
,那么root_id
和parent_id
行不应该被删除。
在上表中,应删除带有id=1
的行。id=2
和id=3
是COMPLETE
,并且超过90天,但由于id=4
是OPEN
,并且具有root_id=2
和parent_id=3
,因此不应删除这三行(id in (2,3,4)
)。id=5
、id=6
和id=7
都是COMPLETE
,但id=7
不超过90天,并且有root_id=5
和parent_id=6
,因此这三行(id=5
、id=6
和id=7
)不应删除。
我尝试了多种内部查询的方法,但我无法为这种情况编写查询。
DB<>Fiddle
3条答案
按热度按时间zvokhttg1#
1.您希望仅删除
COMPLETE
* 且 * >90天的行。1.如果某行满足1.删除条件,但它是某行的子行、父行或根行,而该行由于仍为
OPEN
或太年轻而无法删除,则您不希望删除任何链接的行。对称:锁定父行锁定子行,锁定子行锁定父行。字符串
| ID|根ID|父ID|地位|ts|评论|
| --|--|--|--|--|--|
| 1 |* 空 | 空 *| 完成|2023-08-09 11:14:25.445328|>90天,完整,独立|
我在this db<>fiddle demo中添加了更多的测试用例。最后有一个用例需要澄清:一个可移动的父节点,有两个子节点,一个不可移动,一个可移动。如果您允许删除可移动的子节点,而父节点与不可移动的子节点保持在一起,那么这可以工作。如果您希望保留整个图/族,直到所有节点/成员都可移动,你需要一个递归CTE或者routine来遍历这个图。
ghhaqwfi2#
将您的需求转换为SQL,我得到
字符串
rqenqsqc3#
一步一步-首先识别记录
id
-s,这些记录是具有“OPEN”状态的记录的父记录或根记录,并将它们存储在t
CTE中,然后删除那些“COMPLETE”、超过90天且其id
不在t
中的记录。字符串
DB-fiddle demo