在新时间戳上分区日期以获取以前的时间戳

Partition date on a new timestamp to get previous timestamp

我有一个 table 看起来像:

col1 | col2 | col3 | timestamp
----------------------------------------
  1  |  2   |  3   | 2020-1-16 16:11:10
----------------------------------------
  1  |  2   |  3   | 2020-1-16 16:13:20
----------------------------------------
  1  |  2   |  3   | 2020-1-24 09:29:24

我想创建另一个列,该列提供上一个日期但按天对其进行分区。此外,如果它没有以前的日期,那么它应该 return 相同的日期。它应该是这样的:

col1 | col2 | col3 | timestamp          | prev_timestamp
------------------------------------------------------------
  1  |  2   |  3   | 2020-1-16 16:11:10 | 2020-1-16 16:11:10
------------------------------------------------------------
  1  |  2   |  3   | 2020-1-16 16:13:20 | 2020-1-16 16:11:10
-------------------------------------------------------------
  1  |  2   |  3   | 2020-1-24 9:29:24  | 2020-1-24 09:29:24 

我知道我可以使用 lagpartition by 但是对于时间戳 2020-1-24 9:29:24 它给了我一个我不想要的先前时间戳 2020-1-16 16:13:20

您可以使用 lag() 和条件逻辑:

select 
    col1,
    col2,
    col3,
    case when date_trunc(prev_timestamp) = date_trunc(timestamp) 
        then prev_timestamp 
        else timestamp 
    end prev_timestamp
from (
    select 
        t.*,
        lag(timestamp) over(partition by col1, col2, col3 order by timestamp) prev_timestamp
    from mytable t
) t

您可以像这样重复 lag() 表达式来删除嵌套查询:

select 
    t.*,
    case when date_trunc(lag(timestamp) over(partition by col1, col2, col3 order by timestamp)) = date_trunc(timestamp) 
        then lag(timestamp) over(partition by col1, col2, col3 order by timestamp) 
        else timestamp 
    end prev_timestamp
from mytable t

你可以做你想做的事 lag():

select t.*,
       lag(timestamp, 1, timestamp) over (partition by col1, col2, col3, date(timestamp)
                                          order by timestamp
                                         ) as prev_timestamp
from t;

不需要条件逻辑或子查询。您只是想获得同一天的前一个时间戳,lag() 就可以做到。