Redshift SQL условный плотный ранг - PullRequest
1 голос
/ 13 января 2020

Как бы я "приостановил" звание клиента, если разница в часах по сравнению с предыдущим бронированием меньше 24? то есть условный вывод dense_rank()

with tmp_table as (
select 532 as customer_id, '2020-01-09 18:14:47'::timestamp as log_date union all
select 532 as customer_id, '2020-01-09 18:22:13'::timestamp as log_date union all
select 532 as customer_id, '2020-01-09 18:26:07'::timestamp as log_date union all
--
select 981 as customer_id, '2020-01-09 16:53:52'::timestamp as log_date union all
select 981 as customer_id, '2020-01-09 17:08:28'::timestamp as log_date union all
select 981 as customer_id, '2020-01-11 17:25:24'::timestamp as log_date union all
select 981 as customer_id, '2020-01-14 17:32:10'::timestamp as log_date union all
select 981 as customer_id, '2020-01-14 21:49:12'::timestamp as log_date union all
select 981 as customer_id, '2020-01-17 19:15:22'::timestamp as log_date union all
--
select 1983 as customer_id, '2019-11-05 10:30:58'::timestamp as log_date union all
select 1983 as customer_id, '2019-12-02 13:58:52'::timestamp as log_date union all
select 1983 as customer_id, '2019-12-05 17:25:01'::timestamp as log_date union all
select 1983 as customer_id, '2019-12-11 13:58:24'::timestamp as log_date union all
select 1983 as customer_id, '2019-12-12 14:15:25'::timestamp as log_date
)
select *
, datediff(hour, lag(log_date, 1) over (partition by customer_id order by log_date), log_date) as hour_diff
, rank() over (partition by customer_id order by log_date) as rnk
from tmp_table
order by customer_id, log_date
;

такой:

customer_id|log_date           |hour_diff|rnk|
-----------|-------------------|---------|---|
        532|2020-01-09 18:14:47|         |  1|
        532|2020-01-09 18:22:13|        0|  2|
        532|2020-01-09 18:26:07|        0|  3|
        981|2020-01-09 16:53:52|         |  1|
        981|2020-01-09 17:08:28|        1|  2|
        981|2020-01-11 17:25:24|       48|  3|
        981|2020-01-14 17:32:10|       72|  4|
        981|2020-01-14 21:49:12|        4|  5|
        981|2020-01-17 19:15:22|       70|  6|
       1983|2019-11-05 10:30:58|         |  1|
       1983|2019-12-02 13:58:52|      651|  2|
       1983|2019-12-05 17:25:01|       76|  3|
       1983|2019-12-11 13:58:24|      140|  4|
       1983|2019-12-12 14:15:25|       25|  5|

и я хочу, чтобы он выглядел так:

customer_id|log_date           |hour_diff|rnk|
-----------|-------------------|---------|---|
        532|2020-01-09 18:14:47|         |  1|
        532|2020-01-09 18:22:13|        0|  1|
        532|2020-01-09 18:26:07|        0|  1|
        981|2020-01-09 16:53:52|         |  1|
        981|2020-01-09 17:08:28|        1|  1|
        981|2020-01-11 17:25:24|       48|  2|
        981|2020-01-14 17:32:10|       72|  3|
        981|2020-01-14 21:49:12|        4|  3|
        981|2020-01-17 19:15:22|       70|  4|
       1983|2019-11-05 10:30:58|         |  1|
       1983|2019-12-02 13:58:52|      651|  2|
       1983|2019-12-05 17:25:01|       76|  3|
       1983|2019-12-11 13:58:24|      140|  4|
       1983|2019-12-12 14:15:25|       25|  5|

т.е. если hour_diff > 24 then rank() over (partition by customer_id order by log_date) else "pause rank"

что я пытался сделать, это установить инструкцию case, где, если hour_diff <24, взять <code>lag() из log_date, иначе взять log_date и затем сделать dense_rank() в этом новом log_date

проблема, с которой я столкнулся, заключается в том, что если клиент делает несколько бронирований в течение 24 часов, то он действительно не "ставит на паузу" номер ранга

1 Ответ

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

Вы можете использовать lag(), чтобы определить, где значение должно увеличиваться. Затем используйте накопленную сумму:

select t.*,
       sum( case when prev_log_date > log_date - interval '24 hour' then 0 else 1 end ) over (partition by customer_id order by log_date) as rnk
from (select t.*,
             lag(log_date) over (partition by customer_id order by log_date) as prev_log_date
      from tmp_table t
     ) t;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...