0

我有桌子 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

4

4 回答 4

1

尝试这个

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 
)  
于 2019-11-27T18:22:01.083 回答
0

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

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

Demo

于 2019-11-27T20:00:22.357 回答
0

您可以使用窗口函数来执行此操作——如果我假设您希望每行的最新日期当前月份之前。这使用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<>fiddle。

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

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;
于 2019-11-27T23:00:13.370 回答
0

从问题标题:

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

这是专门解决这样一个事实,即根据Edits 1Edit 3中的预期结果,先前的值应该在“上一个”月份,而不是与行日期在同一个月。

甲骨文设置

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

输出

项目 | 日期 | PREV_DATE          
:--- | :----------------- | :-----------------
一个 | 2000-01-01 00:00:00 | 无效的               
一个 | 2000-10-05 00:00:00 | 2000-01-01 00:00:00
一个 | 2000-12-02 00:00:00 | 2000-10-05 00:00:00
乙| 2000-01-01 00:00:00 |                
B | 2000-01-31 00:00:00 | 无效的               
乙| 2000-02-01 00:00:00 | 2000-01-31 00:00:00
C | 2000-01-01 00:00:00 | 无效的               

db<>在这里摆弄

于 2019-11-27T21:16:51.353 回答