Как мне преобразовать интервал в количество часов с помощью postgres?

#python #sql #postgresql #psycopg2

#datetime #postgresql #интервалы

Вопрос:

Допустим, у меня есть интервал, подобный

 4 days 10:00:00
  

в postgres. Как мне преобразовать это в количество часов (в данном случае 106?) Есть ли функция или я должен стиснуть зубы и сделать что-то вроде

 extract(days, my_interval) * 24   extract(hours, my_interval)
  

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

1. Примечание: Если ваш интервал содержит месяцы или годы, нет определенного ответа о том, сколько в нем часов, поскольку количество дней в месяце или году различается. Так что следите за этим!

2. @Teddy: Точнее, существует несколько определенных ответов 😉

Ответ №1:

Вероятно, самый простой способ — это:

 SELECT EXTRACT(epoch FROM my_interval)/3600
  

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

1. И, возможно, уменьшить или преобразовать результат в целое число, если интервал содержит минуты и / или секунды

2. Извлечь эпоху? О боже, это не пришло бы мне в голову и за миллион лет.

3. ВЫБЕРИТЕ ИЗВЛЕЧЕНИЕ (эпоха ИЗ my_interval / 3600) (интервал имеет встроенную поддержку ‘divide integer’, результат — интервал, а результат извлечения — целое число, а не число с плавающей точкой). Итак. Автокаст / Этаж выполнен.

4. Предупреждение: простое извлечение эпохи неявно предполагает, что один месяц = 30 дней и один год = 365,25 дней.

5. @Teddy что мы можем с этим сделать? Как избежать этой проблемы и получить реальное количество эпох?

Ответ №2:

Если вам нужно целое число, то есть количество дней:

 SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int
  

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

1. Отлично! Спасибо вам за это 🙂 Тем не менее, я обнаружил, что теперь мы можем изменить это на be SELECT extract('epoch' FROM age('2014-08-02'::timestamp)) / 86400 (я использую Pg 9.4), поскольку age(ts) автоматически использовать CURRENT_DATE только один аргумент.

2. Предупреждение: простое извлечение эпохи неявно предполагает, что один месяц = 30 дней и один год = 365,25 дней.

Ответ №3:

Чтобы получить количество дней, самым простым способом было бы:

 SELECT EXTRACT(DAY FROM NOW() - '2014-08-02 08:10:56');
  

Насколько я знаю, он вернет то же самое, что и:

 SELECT (EXTRACT(epoch FROM (SELECT (NOW() - '2014-08-02 08:10:56')))/86400)::int;
  

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

1. Если ваш интервал равен '1 month 0 days' , использование extract(day from …) даст вам 0 результат.

Ответ №4:

 select floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600)), count(*)
from od_a_week
group by floor((date_part('epoch', order_time - '2016-09-05 00:00:00') / 3600));
  

::int Преобразование выполняется по принципу округления.
Если вы хотите получить другой результат, например, округление в меньшую сторону, вы можете использовать соответствующую математическую функцию, такую как floor .

Ответ №5:

Если вы преобразуете поле таблицы:

  1. Определите поле так, чтобы оно содержало секунды:

      CREATE TABLE IF NOT EXISTS test (
         ...
         field        INTERVAL SECOND(0)
     );
      
  2. Извлеките значение. Не забудьте привести к int в противном случае вы можете получить неприятный сюрприз, если интервалы будут большими:

    EXTRACT(EPOCH FROM field)::int

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

1. Я не думаю, что Redshift поддерживает тип данных ИНТЕРВАЛА. Это было бы просто BIGINT.

Ответ №6:

Если вы хотите отобразить свой результат только в типе даты после добавления интервала, попробуйте это

Выберите (current_date интервал ‘x day’)::дата;

Ответ №7:

Я работаю с PostgreSQL 11, и я создал функцию для получения часов между 2 разными временными метками

 create function analysis.calcHours(datetime1 timestamp, datetime2 timestamp)
    returns integer
    language plpgsql as $$
    declare
        diff interval;
    begin
        diff = datetime2 - datetime1;
        return (abs(extract(days from diff))*24   abs(extract(hours from diff)))::integer;
    end; $$;
  

Ответ №8:

          select date 'now()' - date '1955-12-15';
  

Вот простой запрос, который вычисляет общее количество дней.

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

1. Это не принимает значение интервала.