如何删除破坏查询周期性的行?
How can I remove rows that break periodicity with a query?
我有一个 table 如下。数据之间没有周期性,所以我不能使用像 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,但是当它向column2插入Data3时,打破了Data1和Data2之间的周期性。我不想看到在 Data3 之后的查询中检索数据。我希望它像下面这样。
**Column1** | **Column2** | **Timestamp**
Station1 | Data1 | Date1
Station1 | Data2 | Date2
Station1 | Data1 | Date3
Station1 | Data2 | Date4
Station2 | Data1 | Date7
Station2 | Data2 | Date8
我该怎么做才能达到这个结果?提前致谢。
您似乎只在下一行是“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')
您只想显示 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**'
的行。)
简化格式:
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;
我有一个 table 如下。数据之间没有周期性,所以我不能使用像 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,但是当它向column2插入Data3时,打破了Data1和Data2之间的周期性。我不想看到在 Data3 之后的查询中检索数据。我希望它像下面这样。
**Column1** | **Column2** | **Timestamp**
Station1 | Data1 | Date1
Station1 | Data2 | Date2
Station1 | Data1 | Date3
Station1 | Data2 | Date4
Station2 | Data1 | Date7
Station2 | Data2 | Date8
我该怎么做才能达到这个结果?提前致谢。
您似乎只在下一行是“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')
您只想显示 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**'
的行。)
简化格式:
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;