2017-06-20 79 views
0

我有一个样本数据如下,并希望得到所需的o/p,请帮我一些想法。滞后函数得到最后一个不同的值(红移)

我想第三的prev_diff_value的O/P,第4行是2015年1月1日00:00:00,而不是2015年1月2日00:00:00。

with dat as (
      select 1 as id,'20150101 02:02:50'::timestamp as dt union all 
      select 1,'20150101 03:02:50'::timestamp union all 
      select 1,'20150101 04:02:50'::timestamp union all 
      select 1,'20150102 02:02:50'::timestamp union all 
      select 1,'20150102 02:02:50'::timestamp union all 
      select 1,'20150102 02:02:51'::timestamp union all 
      select 1,'20150103 02:02:50'::timestamp union all 
      select 2,'20150101 02:02:50'::timestamp union all 
      select 2,'20150101 03:02:50'::timestamp union all 
      select 2,'20150101 04:02:50'::timestamp union all 
      select 2,'20150102 02:02:50'::timestamp union all 
      select 1,'20150104 02:02:50'::timestamp 
      )-- select * from dat 
    select id , dt , lag(trunc(dt)) over(partition by id order by dt asc) prev_diff_value 
    from dat 
    order by id,dt desc 
O/P : 
    id dt     prev_diff_value 
    1 2015-01-04 02:02:50 2015-01-03 00:00:00 
    1 2015-01-03 02:02:50 2015-01-02 00:00:00 
    1 2015-01-02 02:02:51 2015-01-02 00:00:00 
    1 2015-01-02 02:02:50 2015-01-02 00:00:00 
    1 2015-01-02 02:02:50 2015-01-01 00:00:00 
+0

嗨,你能更好地解释你想在prev_diff_value列中看到什么吗?滞后函数将前一个作为参考,因此它工作正常,您要求该红移。你为什么想回到一步?也许你可以按年 - 月 - 日分组来划分,所以2015-01-02 02:02:50和2015-01-02 02:02:51会被认为是一样的吗? – MiloBellano

+0

好吧..我知道它返回正确的结果,但prev-diff-value中我期望的值是前一天或早些日子而不是前一行 – Fact

回答

1

据我了解你想要得到ID分区中的每一时戳以前不同的日期。然后我会申请lag反对iddate的独特组合,并加入回原始数据集是这样的:

with dat as (
    select 1 as id,'20150101 02:02:50'::timestamp as dt union all 
    select 1,'20150101 03:02:50'::timestamp union all 
    select 1,'20150101 04:02:50'::timestamp union all 
    select 1,'20150102 02:02:50'::timestamp union all 
    select 1,'20150102 02:02:50'::timestamp union all 
    select 1,'20150102 02:02:51'::timestamp union all 
    select 1,'20150103 02:02:50'::timestamp union all 
    select 2,'20150101 02:02:50'::timestamp union all 
    select 2,'20150101 03:02:50'::timestamp union all 
    select 2,'20150101 04:02:50'::timestamp union all 
    select 2,'20150102 02:02:50'::timestamp union all 
    select 1,'20150104 02:02:50'::timestamp 
) 
,dat_unique_lag as (
    select *, lag(date) over(partition by id order by date asc) prev_diff_value 
    from (
     select distinct id,trunc(dt) as date 
     from dat 
    ) 
) 
select * 
from dat 
join dat_unique_lag 
using (id) 
where trunc(dat.dt)=dat_unique_lag.date 
order by id,dt desc; 

然而,这是不是超高性能。如果您的数据的本质是,你必须时间戳当天的数量有限,你可能只是一个条件语句像这样的扩展您的滞后:

with dat as (
    select 1 as id,'20150101 02:02:50'::timestamp as dt union all 
    select 1,'20150101 03:02:50'::timestamp union all 
    select 1,'20150101 04:02:50'::timestamp union all 
    select 1,'20150102 02:02:50'::timestamp union all 
    select 1,'20150102 02:02:50'::timestamp union all 
    select 1,'20150102 02:02:51'::timestamp union all 
    select 1,'20150103 02:02:50'::timestamp union all 
    select 2,'20150101 02:02:50'::timestamp union all 
    select 2,'20150101 03:02:50'::timestamp union all 
    select 2,'20150101 04:02:50'::timestamp union all 
    select 2,'20150102 02:02:50'::timestamp union all 
    select 1,'20150104 02:02:50'::timestamp 
) 
select id, dt, 
case 
    when lag(trunc(dt)) over(partition by id order by dt asc)=trunc(dt) 
    then case 
     when lag(trunc(dt),2) over(partition by id order by dt asc)=trunc(dt) 
     then case 
      when lag(trunc(dt),3) over(partition by id order by dt asc)=trunc(dt) 
      then lag(trunc(dt),4) over(partition by id order by dt asc) 
      else lag(trunc(dt),3) over(partition by id order by dt asc) 
      end 
     else lag(trunc(dt),2) over(partition by id order by dt asc) 
     end 
    else lag(trunc(dt)) over(partition by id order by dt asc) 
end as prev_diff_value 
from dat 
order by id,dt desc; 

基本上,你看看以前的记录,如果它不不适合你,那么你在这之前回顾记录等等,直到你找到正确的记录或用完你的陈述深度。这里看起来直到第四回纪录。