在特定条件下使用 LAG 函数

Posted

技术标签:

【中文标题】在特定条件下使用 LAG 函数【英文标题】:Using LAG function with a specific condition 【发布时间】:2020-04-22 09:29:56 【问题描述】:

我有一个以下格式的表格。

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

但是,我希望以这样一种方式创建此结果表,即对于状态为“ON”的行,to_date 应提供下一个“OFF”日期的日期。下面是它的样子。

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

【问题讨论】:

【参考方案1】:

我认为您想要一个带有选项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

第一个查询:

身份证 | FROM_DATE | TO_DATE |地位 ----: | :-------- | :-------- | :----- 15643 | 20 年 3 月 10 日 | 20 年 3 月 20 日 |在 15643 | 20 年 3 月 15 日 | |测试 15643 | 20 年 3 月 20 日 | |离开

第二次查询:

身份证 | FROM_DATE | TO_DATE |地位 ----: | :-------- | :-------- | :----- 15643 | 20 年 3 月 10 日 | 20 年 3 月 19 日 |在 15643 | 20 年 3 月 15 日 | 20 年 3 月 19 日 |测试 15643 | 20 年 3 月 20 日 | |离开

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

身份证 | FROM_DATE | TO_DATE |地位 ----: | :-------- | :-------- | :----- 15643 | 20 年 3 月 10 日 | 20 年 3 月 19 日 |在 15643 | 20 年 3 月 15 日 | 20 年 3 月 19 日 |测试 15643 | 20 年 3 月 20 日 | |离开

【讨论】:

以上是关于在特定条件下使用 LAG 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何为不同的观察组使用 LAG 和 LEAD 窗口函数

分析函数 - 使用 LAG() 比较值

求教SAS中LAG函数的使用

Oracle分析函数之Lag和Lead()使用

具有动态偏移量的 TSQL 复制 LAG() 函数

Spark Dataframe - 窗口函数 - 插入和更新输出的滞后和领先