删除除特定值和接下来的两行之外的所有内容

Delete everything except certain value and the next two rows

我需要帮助来删除使用 SQL 语句,我可以删除除值包含 'Start' 之外的所有内容 Value1 字段和下面接下来的两行包含 Keep* 值。请记住,Keep* 值也可以是其他不同的值,我只是以 Keep 为例。

谢谢

**ID    DocumentName    Value1      Value2**
__  ____________    ______      _____
1   Doc1             AB        123rt
2   Doc1             CD        4543
3   Doc1             CE         fgf
4   Doc1             Csafsaf    fghfdg
5   Doc1             sdsaff     sdsa
6   Doc1             Start      From
7   Doc1            Keep2      Stay2
8   Doc1            Keep3      Stay3
9   Doc1            Stop        end
10  Doc1          hjkhjkiu     iuoiuio
11  Doc1          zxzfd         bxgx
12  Doc2           AB          123rt
13  Doc2          CD           4543
14  Doc2          CE           fgf
15  Doc2        Csafsaf     fghfdg
16  Doc2         sdsaff        sdsa
17  Doc2         Start         From
18  Doc2         Keep5        Stay5
19  Doc2         Keep6        Stay6
20  Doc2         Stop          end
21  Doc2        hjkhjkiu    iuoiuio
22  Doc2         zxzfd       bxgx
23  Doc3         dds          gdgd
24  Doc3         jhkjh       jhjkh
25  Doc3        jkkjh         fgf
26  Doc3      hnmnbjkhjkiu    mnbmn
27  Doc3        nmb           nbmn
28  Doc3       Start          From
29  Doc3       Keep7         Stay7
30  Doc3        Keep8        Stay8
31  Doc3        Stop          end

基本上我想要这些值

**ID    DocumentName    Value1      Value2**
__  ____________    ______          _____
6   Doc1             Start      From
7   Doc1            Keep2      Stay2
8   Doc1            Keep3      Stay3
17  Doc2         Start         From
18  Doc2         Keep5        Stay5
19  Doc2         Keep6        Stay6
28  Doc3       Start          From
29  Doc3       Keep7         Stay7
30  Doc3        Keep8        Stay8

如果 id 没有间隙,你可以这样做:

delete from t
    where (select t2.id
           from t t2
           where t2.documentname = t.documentname and
                 t2.value = 'Start'
          ) not in (t.id, t.id + 1, t.id + 2) and
          (t.value = 'Start' or t.value like 'Keep%')

重要的是,这假定每个文档只有一个起始行并且 id 中没有间隙。

使用 CTElag() window 函数:

with cte as (
  select *,
    lag(Value1, 1) over (partition by DocumentName order by ID) prev1,
    lag(Value1, 2) over (partition by DocumentName order by ID) prev2
  from tablename  
)
delete from cte
where 'Start' not in (Value1, coalesce(prev1, ''), coalesce(prev2, ''))

参见demo
结果:

> ID | DocumentName | Value1 | Value2
> -: | :----------- | :----- | :-----
>  6 | Doc1         | Start  | From  
>  7 | Doc1         | Keep2  | Stay2 
>  8 | Doc1         | Keep3  | Stay3 
> 17 | Doc2         | Start  | From  
> 18 | Doc2         | Keep5  | Stay5 
> 19 | Doc2         | Keep6  | Stay6 
> 28 | Doc3         | Start  | From  
> 29 | Doc3         | Keep7  | Stay7 
> 30 | Doc3         | Keep8  | Stay8