Дата раздела на новой отметке времени, чтобы получить предыдущую отметку времени - PullRequest
2 голосов
/ 27 января 2020

У меня есть таблица, которая выглядит следующим образом:

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

Я хочу создать еще один столбец, в котором будет указана предыдущая дата, но я разделю ее по дням. Также, если у него нет предыдущей даты, он должен вернуть ту же дату. Это должно выглядеть следующим образом:

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 

Я знаю, что могу использовать lag и partition by, но затем для отметки времени 2020-1-24 9:29:24 это дает мне предыдущую отметку времени 2020-1-16 16:13:20, которую я не хочу .

Ответы [ 2 ]

1 голос
/ 27 января 2020

Вы можете делать, что хотите, только с помощью lag():

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

Никаких условных логи c или подзапрос не требуется. Вы просто хотите получить предыдущую временную метку в тот же день, и lag() делает это.

1 голос
/ 27 января 2020

Вы можете использовать lag() и условные логики c:

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
...