如何通过查询删除打破周期性的行?

Posted

技术标签:

【中文标题】如何通过查询删除打破周期性的行?【英文标题】:How can I remove rows that break periodicity with a query? 【发布时间】:2020-08-15 13:25:14 【问题描述】:

我有一张如下表。数据之间没有周期性,所以我不能使用 row_number() 或 rank 等函数。

**Column1**  |  **Column2**  |  **Timestamp**
Station1     |  Data1        | Date1    
Station1     |  Data2        | Date2
Station1     |  Data1        | Date3
Station1     |  Data2        | Date4
Station1     |  **Data3**    | Date5
Station1     |  Data2        | Date6
Station2     |  Data1        | Date7
Station2     |  Data2        | Date8
Station2     |  **Data3**    | Date9
Station2     |  Data2        | Date10

column2 中的普通数据类似于 Data1 和 Data2,但是当它插入 Data3 到 column2 时,它打破了 Data1 和 Data2 之间的周期性。我不想看到从 Data3 之后的查询中检索数据。我希望它像下面这样。

**Column1**  |  **Column2**  |  **Timestamp**
Station1     |  Data1        | Date1    
Station1     |  Data2        | Date2
Station1     |  Data1        | Date3
Station1     |  Data2        | Date4
Station2     |  Data1        | Date7
Station2     |  Data2        | Date8

我可以做些什么来达到这个结果?提前致谢。

【问题讨论】:

【参考方案1】:

您似乎只在下一行是“data2”时才需要“data1”,而只有在前一行是“data1”时才需要“data2”。所以:

select t.*
from (select t.*,
             lag(column2) over (partition by column1 order by timestamp) as prev_column2,
             lead(column2) over (partition by column1 order by timestamp) as next_column2
      from t
     ) t
where (column2 = 'data1' and next_column2 = 'data2') or
      (column2 = 'data1' and prev_column2 = 'data1')

【讨论】:

【参考方案2】:

您只想显示 Data1 和 Data2 行,但只显示前一个这样的行是其他数据的那些。换句话说,您想要显示交替的 Data1 和 Data2 行。这可以通过LAST_VALUE 实现:

select column1, column2, timestmp
from
(
  select 
    column1, column2, timestmp,
    last_value(case when column2 in ('Data1', 'Data2') then column2 end ignore nulls)
     over
      (order by timestmp rows between unbounded preceding and 1 preceding) as last_col2
  from mytable
)
where column2 in ('Data1', 'Data2')
and decode(column2, last_col2, 'same', 'different') = 'different'
order by timestmp;

演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=c8611e24eb0d54ba65e89391d11332cd

(但是,如果允许始终删除 Data3 行和下一行,则可以改用 LAG 并关闭所有 column2 = '**Data3**' or lag(column2) = '**Data3**' 所在的行。)

【讨论】:

【参考方案3】:

简化格式:

SQLFiddle

SELECT X.column1, x.column2, x.timestamp FROM 
(
SELECT A.*, LEAD(COLUMN2) OVER(ORDER BY COLUMN1, column2) NEXT_VALUE
FROM TABLE1 A
) X WHERE 'Data3' not IN (COLUMN2, NEXT_VALUE) 
ORDER BY 1, 2;

【讨论】:

以上是关于如何通过查询删除打破周期性的行?的主要内容,如果未能解决你的问题,请参考以下文章

ES 索引生命周期管理策略

ES 索引生命周期管理策略

如何向 Celery (celerybeat) 动态添加/删除周期性任务

查询以从与给定值相同的列中选择值,但不同的行

如何结合SQL解析,设置ClickHouse表的最佳生命周期?

LiveGBS国标GB_T28181视频平台如何配置全局全局报警订阅周期(秒)快捷配置开启报警告警订阅周期