Oracle SQL:滞后于一系列值
Oracle SQL: LAG over a range of values
我们如何在值的范围内使用分析函数 LAG。
如果分区中没有较早 in_date 的记录,则它应该 return null 否则,前一个 in_date
的年月
示例:
CID IN_DATE
1 2020-05-29
1 2020-06-10
1 2020-06-21
1 2020-07-08
1 2020-08-11
1 2020-10-01
2 2020-05-05
2 2020-05-03
2 2020-06-01
2 2020-06-02
2 2020-06-03
预期输出,
CID IN_DATE LAG
1 2020-05-29 null
1 2020-06-10 2020-05
1 2020-06-21 2020-05
1 2020-07-08 2020-06
1 2020-08-11 2020-07
1 2020-10-01 2020-08
2 2020-05-05 null
2 2020-05-03 null
2 2020-06-01 2020-05
2 2020-06-02 2020-05
2 2020-06-03 2020-05
2 2020-07-03 2020-06
2 2020-08-13 2020-07
我当前的查询使用 LAG returns 以下
with data as (
select 1 CID, TO_DATE('2020-05-29','YYYY-MM-DD') IN_DATE from dual union all
select 1, TO_DATE('2020-06-10','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-06-21','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-07-08','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-08-11','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-05','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-03','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-01','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-02','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-03','YYYY-MM-DD') from dual
)
select CID,
to_char(TO_DATE(IN_DATE), 'YYYY-MM-DD') IN_DATE,
LAG(to_char(TO_DATE(IN_DATE), 'YYYY-MM')) OVER (PARTITION BY CID
ORDER BY to_char(TO_DATE(IN_DATE), 'YYYY-MM') ) LAG
from data
当前结果
CID IN_DATE LAG
1 1 2020-05-29 NULL
2 1 2020-06-10 2020-05
3 1 2020-06-21 2020-06
4 1 2020-07-08 2020-06
5 1 2020-08-11 2020-07
6 2 2020-05-05 NULL
7 2 2020-05-03 2020-05
8 2 2020-06-01 2020-05
9 2 2020-06-02 2020-06
10 2 2020-06-03 2020-06
看起来,LAG 不允许我们使用分区超范围
是否有替代方法
记录 7 的滞后字段不为空,因为滞后函数正在查找记录 6。
我可以通过两种方式来澄清您的问题:
如果分区中没有较早 in_date
的记录,您想 return null
如果 in_date 来自当前记录 in_date 之前一个月的分区中没有记录,你想 return null =10=]
如果您想要本月之前的上个月,则不需要 LAG()
。我会建议:
with data as (
select 1 CID, TO_DATE('2020-05-29','YYYY-MM-DD') IN_DATE from dual union all
select 1, TO_DATE('2020-06-10','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-06-21','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-07-08','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-08-11','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-05','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-03','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-01','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-02','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-03','YYYY-MM-DD') from dual
)
select CID,
to_char(TO_DATE(IN_DATE), 'YYYY-MM-DD') IN_DATE,
TO_CHAR(MAX(IN_DATE) OVER (PARTITION BY CID
ORDER BY TRUNC(IN_DATE, 'MON')
RANGE BETWEEN UNBOUNDED PRECEDING AND INTERVAL '1' MONTH PRECEDING
),
'YYYY-MM') as LAG
from data;
Here 是一个 db<>fiddle.
我们如何在值的范围内使用分析函数 LAG。 如果分区中没有较早 in_date 的记录,则它应该 return null 否则,前一个 in_date
的年月示例:
CID IN_DATE
1 2020-05-29
1 2020-06-10
1 2020-06-21
1 2020-07-08
1 2020-08-11
1 2020-10-01
2 2020-05-05
2 2020-05-03
2 2020-06-01
2 2020-06-02
2 2020-06-03
预期输出,
CID IN_DATE LAG
1 2020-05-29 null
1 2020-06-10 2020-05
1 2020-06-21 2020-05
1 2020-07-08 2020-06
1 2020-08-11 2020-07
1 2020-10-01 2020-08
2 2020-05-05 null
2 2020-05-03 null
2 2020-06-01 2020-05
2 2020-06-02 2020-05
2 2020-06-03 2020-05
2 2020-07-03 2020-06
2 2020-08-13 2020-07
我当前的查询使用 LAG returns 以下
with data as (
select 1 CID, TO_DATE('2020-05-29','YYYY-MM-DD') IN_DATE from dual union all
select 1, TO_DATE('2020-06-10','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-06-21','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-07-08','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-08-11','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-05','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-03','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-01','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-02','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-03','YYYY-MM-DD') from dual
)
select CID,
to_char(TO_DATE(IN_DATE), 'YYYY-MM-DD') IN_DATE,
LAG(to_char(TO_DATE(IN_DATE), 'YYYY-MM')) OVER (PARTITION BY CID
ORDER BY to_char(TO_DATE(IN_DATE), 'YYYY-MM') ) LAG
from data
当前结果
CID IN_DATE LAG
1 1 2020-05-29 NULL
2 1 2020-06-10 2020-05
3 1 2020-06-21 2020-06
4 1 2020-07-08 2020-06
5 1 2020-08-11 2020-07
6 2 2020-05-05 NULL
7 2 2020-05-03 2020-05
8 2 2020-06-01 2020-05
9 2 2020-06-02 2020-06
10 2 2020-06-03 2020-06
看起来,LAG 不允许我们使用分区超范围 是否有替代方法
记录 7 的滞后字段不为空,因为滞后函数正在查找记录 6。
我可以通过两种方式来澄清您的问题:
如果分区中没有较早 in_date
的记录,您想 return null如果 in_date 来自当前记录 in_date 之前一个月的分区中没有记录,你想 return null =10=]
如果您想要本月之前的上个月,则不需要 LAG()
。我会建议:
with data as (
select 1 CID, TO_DATE('2020-05-29','YYYY-MM-DD') IN_DATE from dual union all
select 1, TO_DATE('2020-06-10','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-06-21','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-07-08','YYYY-MM-DD') from dual union all
select 1, TO_DATE('2020-08-11','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-05','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-05-03','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-01','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-02','YYYY-MM-DD') from dual union all
select 2, TO_DATE('2020-06-03','YYYY-MM-DD') from dual
)
select CID,
to_char(TO_DATE(IN_DATE), 'YYYY-MM-DD') IN_DATE,
TO_CHAR(MAX(IN_DATE) OVER (PARTITION BY CID
ORDER BY TRUNC(IN_DATE, 'MON')
RANGE BETWEEN UNBOUNDED PRECEDING AND INTERVAL '1' MONTH PRECEDING
),
'YYYY-MM') as LAG
from data;
Here 是一个 db<>fiddle.