在特定条件下使用 LAG 函数

Using LAG function with a specific condition

我有一个 table 格式如下。

我可以使用 oracle SQL 中的 LAG 函数将 table 转换为以下格式 SQL。

但是,我希望创建此结果 table 时,对于状态为 'ON' 的行,to_date 应提供下一个 'OFF' 的日期] 日期。下面是它应该是什么样子。

我们如何在 Oracle SQL 中做到这一点?

我认为你想要一个带有选项 ignore nulls 的条件 lead():

select 
    id,
    date from_date,
    case when status = 'ON' 
        then lead(case when status = 'OFF' then date end ignore nulls) 
            over(partition by id order by date)
    end to_date,
    status
from mytable

为了更好地匹配预期结果,我们将函数应用于除 'OFF' 以外的任何状态,并从结果中提取 1 天:

select 
    id,
    date from_date,
    case when status <> 'OFF' 
        then lead(case when status = 'OFF' then date end ignore nulls) 
            over(partition by id order by date) - 1
    end to_date,
    status
from mytable

如果您还想要 'OFF' 行的下一个 'ON' 日期:

select 
    id,
    date from_date,
    case when status <> 'OFF' 
        then lead(case when status = 'OFF' then date end ignore nulls) 
            over(partition by id order by date) - 1
        else lead(case when status = 'ON' then date end ignore nulls) 
            over(partition by id order by date) - 1
    end to_date,
    status
from mytable

Demo on DB Fiddlde

第一次查询:

   ID | FROM_DATE | TO_DATE   | STATUS
----: | :-------- | :-------- | :-----
15643 | 10-MAR-20 | 20-MAR-20 | ON    
15643 | 15-MAR-20 | null      | test  
15643 | 20-MAR-20 | null      | OFF   

第二次查询:

   ID | FROM_DATE | TO_DATE   | STATUS
----: | :-------- | :-------- | :-----
15643 | 10-MAR-20 | 19-MAR-20 | ON    
15643 | 15-MAR-20 | 19-MAR-20 | test  
15643 | 20-MAR-20 | null      | OFF   

第三个查询(您看不出与第二个查询的区别,因为没有 'OFF' 行和下一个 'ON'):

   ID | FROM_DATE | TO_DATE   | STATUS
----: | :-------- | :-------- | :-----
15643 | 10-MAR-20 | 19-MAR-20 | ON    
15643 | 15-MAR-20 | 19-MAR-20 | test  
15643 | 20-MAR-20 | null      | OFF