繁体   English   中英

如何从分区中给定的行日期中获取最近的上个月的日期?

[英]How can I get the date with the closest previous month from a given row date in a partition?

我有桌子A

Item     Date    

a        01-01-2000   
a        10-05-2000    
a        12-02-2000    
b        01-01-2000    
b        01-31-2000    
b        02-01-2000    
c        01-01-2000  

我想要此输出,同一项目的给定行的最接近的上一个日期

Item     Date          closest_day

a        01-01-2000    null
a        10-05-2000    01-01-2000
a        12-02-2000    10-05-2000
b        01-01-2000    null
b        01-31-2000    null
b        02-01-2000    01-31-2000
c        01-01-2000    null

尝试这个

with t as(
select 'a' c,to_date('01.01.2000','mm.dd.yyyy') d from dual
union all   
select 'a' ,to_date('10.05.2000','mm.dd.yyyy')  from dual    
union all   
select 'a' ,to_date('12.02.2000','mm.dd.yyyy')  from dual    
union all   
select 'b' ,to_date('01.01.2000','mm.dd.yyyy')  from dual    
union all   
select 'b' ,to_date('01.31.2000','mm.dd.yyyy')  from dual   
union all   
select 'b' ,to_date('02.01.2000','mm.dd.yyyy')  from dual    
union all   
select 'c' ,to_date('01.01.2000','mm.dd.yyyy')  from dual
)
select t.c,t.d,LAG (t.d) over ( partition by t.c order by t.d ) from t 

最接近的日期必须在不同的月份?

 with t as(
select 'a' c,to_date('01.01.2000','mm.dd.yyyy') d from dual
union all   
select 'a' ,to_date('10.05.2000','mm.dd.yyyy')  from dual    
union all   
select 'a' ,to_date('12.02.2000','mm.dd.yyyy')  from dual    
union all   
select 'b' ,to_date('01.01.2000','mm.dd.yyyy')  from dual    
union all   
select 'b' ,to_date('01.31.2000','mm.dd.yyyy')  from dual   
union all   
select 'b' ,to_date('02.01.2000','mm.dd.yyyy')  from dual    
union all   
select 'c' ,to_date('01.01.2000','mm.dd.yyyy')  from dual
)
select c,d,case when trunc(d,'Month')<>trunc(closest_d,'Month') then closest_d else null end closest_d  from(
select t.c,t.d,LAG (t.d) over ( partition by t.c order by t.d ) closest_d from t 
)  

您可以使用包含连接条件内日期之间不等式的自左连接:

with t2 as
(
select t1.Item,t1."Date" as t1_Date, t2."Date" as t2_Date
  from t t1
  left join t t2 on t1."Date">t2."Date" and t1.Item = t2.Item
)
select Item, t1_Date as "Date", max(t2_Date) as "Closest Day"
  from t2
 group by Item, t1_Date 
 order by Item, t1_Date

演示版

我想要此输出,同一项目的给定行的最接近的上一个日期

这正是窗口函数lag()作用:

select
    t.*, 
    lag(date) over(partition by item order by date) closest_day
from mytable t

从问题标题:

如何从分区中给定的行日期中获取最近的上个月的日期?

这是专门针对以下事实:根据编辑1编辑3中的预期结果,前一个值应位于“上一个”月中,而不应与行日期位于同一月中。

Oracle安装程序

CREATE TABLE test_data ( item, "date" ) AS
SELECT 'A', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 'A', DATE '2000-10-05' FROM DUAL UNION ALL
SELECT 'A', DATE '2000-12-02' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-01-31' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-02-01' FROM DUAL UNION ALL
SELECT 'C', DATE '2000-01-01' FROM DUAL;

查询

SELECT t.*,
       ( SELECT MAX( "date" )
         FROM   test_data p
         WHERE  p.item = t.item
         AND    p."date" < TRUNC( t."date", 'MM' )
       ) AS prev_date
FROM   test_data t

输出

\n 项目|  日期|  PREV_DATE          \n :--- |  :------------------ |  :------------------\n A |  2000-01-01 00:00:00 |  空值               \n A |  2000-10-05 00:00:00 |  2000-01-01 00:00:00\n A |  2000-12-02 00:00:00 |  2000-10-05 00:00:00\n B |  2000-01-01 00:00:00 |  空值               \n B |  2000-01-31 00:00:00 |  空值               \n B |  2000-02-01 00:00:00 |  2000-01-31 00:00:00\n C |  2000-01-01 00:00:00 |  空值               \n

db <> 在这里拨弄

您可以使用窗口函数来执行此操作-如果我假设您希望每一行的当前日期之前为最新日期。 这使用range窗口定义:

SELECT t.*,
       MAX("date") OVER (PARTITION BY item
                         ORDER BY TRUNC(t."date", 'MON')
                         RANGE BETWEEN UNBOUNDED PRECEDING AND INTERVAL '1' MONTH PRECEDING
                        ) AS prev_date
FROM test_data t;

是db <>小提琴。

如果您特别想要上一个日历月的结果,则:

SELECT t.*,
       MAX("date") OVER (PARTITION BY item
                         ORDER BY TRUNC(t."date", 'MON')
                         RANGE BETWEEN INTERVAL '1' MONTH PRECEDING AND INTERVAL '1' MONTH PRECEDING
                        ) AS prev_date
FROM test_data t;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM