2017-06-20 75 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; 

基本上,你看看以前的記錄,如果它不不適合你,那麼你在這之前回顧記錄等等,直到你找到正確的記錄或用完你的陳述深度。這裏看起來直到第四回紀錄。