在特定条件下使用 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
第一次查询:
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
我有一个 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
第一次查询:
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