Как я могу найти возникновение определенного периода времени дня между двумя временными метками?

#sql #amazon-redshift

#sql #amazon-redshift

Вопрос:

У меня есть следующая таблица:

 Id | starts         | ends
1  | 21/10/21 03:00 | 21/10/21 15:00
2  | 22/10/21 04:00 | 24/10/21 18:00
3  | 25/10/21 18:00 | 25/10/21 21:00
 

Я хотел бы узнать часы, приходящиеся на период с 23:00 до 06:00 для каждого идентификатора.
Вывод должен выглядеть следующим образом,

 ID | Hours
1  |  3
2  |  16
3  |  0
 

Поскольку это временная метка и после 24 она возвращается к 1. Мне трудно вывести какую-либо логику.

Комментарии:

1. Я удалил тег postgres. Я предполагаю, что вы используете Redshift и ошибочно полагаете, что он на самом деле похож на Postgres.

2. @GordonLinoff … ну, в некотором смысле Redshift похож на Postgres, поскольку первый основан на форке из довольно ранней версии последнего. Итак, есть некоторые сходства, хотя на данный момент синтаксис и поведение могут сильно отличаться в зависимости от запроса.

3. @TimBiegeleisen . , , Postgres 13 даже не особенно похож на Postgres 8 больше. И это игнорирует все изменения, внесенные Redshift … и функциональность, которую он пропустил.

Ответ №1:

Этот запрос дает вам результат, который вы хотите. Имейте в виду, что вам нужно протестировать его в большем количестве случаев.

 with between_23_06 as (
  SELECT Id
        ,CASE
           WHEN DATE_PART(h, starts) < 6 THEN 6 - DATE_PART(h, starts)
           ELSE 0
         END as starts_bf_6
        ,CASE
           WHEN DATE_PART(h, starts) = 23 THEN 1
           ELSE 0
         END as ends_af_23
        ,CASE
           WHEN DATE_PART(d, ends) - DATE_PART(d, starts) > 1 THEN (DATE_PART(d, ends) - DATE_PART(d, starts)) * 7
           ELSE 0
         END as all_day
    FROM dwh_staging.drop_me
)
select Id, (starts_bf_6   ends_af_23   all_day) as Hours
  from between_23_06 
 order by 1